enabled by setting $wgUsePigLatinVariant to true.
* Added RecentChangesPurgeRows hook to allow extensions to purge data that
depends on the recentchanges table.
+* Added JS config values wgDiffOldId/wgDiffNewId to the output of diff pages.
=== Languages updated in 1.30 ===
*/
$wgExternalDiffEngine = false;
+/**
+ * wikidiff2 supports detection of changes in moved paragraphs.
+ * This setting controls the maximum number of paragraphs to compare before it bails out.
+ * Supported values:
+ * * 0: detection of moved paragraphs is disabled
+ * * int > 0: maximum number of paragraphs to compare
+ * Note: number of paragraph comparisons is in O(n^2).
+ * This setting is only effective if the wikidiff2 PHP/HHVM module is used as diffengine.
+ * See $wgExternalDiffEngine.
+ *
+ * @since 1.30
+ */
+$wgWikiDiff2MovedParagraphDetectionCutoff = 0;
+
/**
* Disable redirects to special pages and interwiki redirects, which use a 302
* and have no "redirected from" link.
* @param Article $article
*/
public function __construct( Article $article ) {
- global $wgOOUIEditPage;
-
$this->mArticle = $article;
$this->page = $article->getPage(); // model object
$this->mTitle = $article->getTitle();
$handler = ContentHandler::getForModelID( $this->contentModel );
$this->contentFormat = $handler->getDefaultFormat();
- $this->oouiEnabled = $wgOOUIEditPage;
+ $this->oouiEnabled = $this->context->getConfig()->get( 'OOUIEditPage' );
}
/**
* interpret a given string as being a JavaScript expression, instead of string
* data.
*
- * Example:
+ * @par Example:
+ * @code
+ * Xml::encodeJsVar( new XmlJsCode( 'a + b' ) );
+ * @encode
*
- * Xml::encodeJsVar( new XmlJsCode( 'a + b' ) );
- *
- * Returns "a + b".
+ * This returns "a + b".
*
* @note As of 1.21, XmlJsCode objects cannot be nested inside objects or arrays. The sole
* exception is the $args argument to Xml::encodeJsCall() because Xml::encodeJsVar() is
* @inheritdoc
*/
public function isSelected( FormOptions $opts ) {
- $values = explode(
- ChangesListStringOptionsFilterGroup::SEPARATOR,
- $opts[ $this->getGroup()->getName() ]
- );
+ $option = $opts[ $this->getGroup()->getName() ];
+ if ( $option === ChangesListStringOptionsFilterGroup::ALL ) {
+ return true;
+ }
+
+ $values = explode( ChangesListStringOptionsFilterGroup::SEPARATOR, $option );
return in_array( $this->getName(), $values );
}
}
}
}
+ $out->addJsConfigVars( [
+ 'wgDiffOldId' => $this->mOldid,
+ 'wgDiffNewId' => $this->mNewid,
+ ] );
+
# Make "next revision link"
# Skip next link on the top revision
if ( $samePage && !$this->mNewRev->isCurrent() ) {
$wgExternalDiffEngine = false;
}
+ // Better external diff engine, the 2 may some day be dropped
+ // This one does the escaping and segmenting itself
if ( function_exists( 'wikidiff2_do_diff' ) && $wgExternalDiffEngine === false ) {
- # Better external diff engine, the 2 may some day be dropped
- # This one does the escaping and segmenting itself
- $text = wikidiff2_do_diff( $otext, $ntext, 2 );
+ $wikidiff2Version = phpversion( 'wikidiff2' );
+ if (
+ $wikidiff2Version !== false &&
+ version_compare( $wikidiff2Version, '0.3.0', '>=' )
+ ) {
+ $text = wikidiff2_do_diff(
+ $otext,
+ $ntext,
+ 2,
+ $this->getConfig()->get( 'WikiDiff2MovedParagraphDetectionCutoff' )
+ );
+ } else {
+ // Don't pass the 4th parameter for compatibility with older versions of wikidiff2
+ $text = wikidiff2_do_diff(
+ $otext,
+ $ntext,
+ 2
+ );
+
+ // Log a warning in case the configuration value is set to not silently ignore it
+ if ( $this->getConfig()->get( 'WikiDiff2MovedParagraphDetectionCutoff' ) > 0 ) {
+ wfLogWarning( '$wgWikiDiff2MovedParagraphDetectionCutoff is set but has no
+ effect since the used version of WikiDiff2 does not support it.' );
+ }
+ }
+
$text .= $this->debug( 'wikidiff2' );
return $text;
"\nBacktrace:\n" .
MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
} else {
- return self::getShowBacktraceError( $e );
+ return self::getShowBacktraceError( $e ) . "\n";
}
}
$vars[] = '$wgShowDBErrorBacktrace = true;';
}
$vars = implode( ' and ', $vars );
- return "Set $vars at the bottom of LocalSettings.php to show detailed debugging information\n";
+ return "Set $vars at the bottom of LocalSettings.php to show detailed debugging information.";
}
/**
return "$select<br />\n$textbox";
}
+ protected function getOOUIModules() {
+ return [ 'mediawiki.widgets.SelectWithInputWidget' ];
+ }
+
public function getInputOOUI( $value ) {
- return false;
+ $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.SelectWithInputWidget.styles' );
+
+ # TextInput
+ $textAttribs = [
+ 'id' => $this->mID . '-other',
+ 'name' => $this->mName . '-other',
+ 'size' => $this->getSize(),
+ 'class' => [ 'mw-htmlform-select-and-other-field' ],
+ 'data-id-select' => $this->mID,
+ 'value' => $value[2],
+ ];
+
+ $allowedParams = [
+ 'required',
+ 'autofocus',
+ 'multiple',
+ 'disabled',
+ 'tabindex',
+ 'maxlength',
+ ];
+
+ $textAttribs += OOUI\Element::configFromHtmlAttributes(
+ $this->getAttributes( $allowedParams )
+ );
+
+ if ( $this->mClass !== '' ) {
+ $textAttribs['classes'] = [ $this->mClass ];
+ }
+
+ # DropdownInput
+ $dropdownInputAttribs = [
+ 'name' => $this->mName,
+ 'id' => $this->mID,
+ 'options' => $this->getOptionsOOUI(),
+ 'value' => $value[1],
+ ];
+
+ $allowedParams = [
+ 'tabindex',
+ 'disabled',
+ ];
+
+ $dropdownInputAttribs += OOUI\Element::configFromHtmlAttributes(
+ $this->getAttributes( $allowedParams )
+ );
+
+ if ( $this->mClass !== '' ) {
+ $dropdownInputAttribs['classes'] = [ $this->mClass ];
+ }
+
+ return $this->getInputWidget( [
+ 'textinput' => $textAttribs,
+ 'dropdowninput' => $dropdownInputAttribs,
+ 'or' => false,
+ ] );
+ }
+
+ public function getInputWidget( $params ) {
+ return new Mediawiki\Widget\SelectWithInputWidget( $params );
}
/**
return "$select<br />\n$textbox";
}
+ protected function shouldInfuseOOUI() {
+ return true;
+ }
+
+ protected function getOOUIModules() {
+ return [ 'mediawiki.widgets.SelectWithInputWidget' ];
+ }
+
public function getInputOOUI( $value ) {
- return false;
+ $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.SelectWithInputWidget.styles' );
+
+ $valInSelect = false;
+ if ( $value !== false ) {
+ $value = strval( $value );
+ $valInSelect = in_array(
+ $value, HTMLFormField::flattenOptions( $this->getOptions() ), true
+ );
+ }
+
+ # DropdownInput
+ $dropdownAttribs = [
+ 'id' => $this->mID,
+ 'name' => $this->mName,
+ 'options' => $this->getOptionsOOUI(),
+ 'value' => $valInSelect ? $value : 'other',
+ 'class' => [ 'mw-htmlform-select-or-other' ],
+ ];
+
+ $allowedParams = [
+ 'disabled',
+ 'tabindex',
+ ];
+
+ $dropdownAttribs += OOUI\Element::configFromHtmlAttributes(
+ $this->getAttributes( $allowedParams )
+ );
+
+ # TextInput
+ $textAttribs = [
+ 'id' => $this->mID . '-other',
+ 'name' => $this->mName . '-other',
+ 'size' => $this->getSize(),
+ 'value' => $valInSelect ? '' : $value,
+ ];
+
+ $allowedParams = [
+ 'required',
+ 'autofocus',
+ 'multiple',
+ 'disabled',
+ 'tabindex',
+ 'maxlength',
+ ];
+
+ $textAttribs += OOUI\Element::configFromHtmlAttributes(
+ $this->getAttributes( $allowedParams )
+ );
+
+ if ( $this->mClass !== '' ) {
+ $textAttribs['classes'] = [ $this->mClass ];
+ }
+ if ( $this->mPlaceholder !== '' ) {
+ $textAttribs['placeholder'] = $this->mPlaceholder;
+ }
+
+ return $this->getInputWidget( [
+ 'textinput' => $textAttribs,
+ 'dropdowninput' => $dropdownAttribs,
+ 'or' => true,
+ ] );
+ }
+
+ public function getInputWidget( $params ) {
+ return new Mediawiki\Widget\SelectWithInputWidget( $params );
}
/**
* @since 1.17
*/
class SqliteInstaller extends DatabaseInstaller {
- const MINIMUM_VERSION = '3.3.7';
+
+ public $minimumVersion = '3.3.7';
/**
* @var DatabaseSqlite
$result = Status::newGood();
// Bail out if SQLite is too old
$db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
- if ( version_compare( $db->getServerVersion(), self::MINIMUM_VERSION, '<' ) ) {
- $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), self::MINIMUM_VERSION );
+ if ( version_compare( $db->getServerVersion(), $this->minimumVersion, '<' ) ) {
+ $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), $this->minimumVersion );
}
// Check for FTS3 full-text search module
if ( DatabaseSqlite::getFulltextSearchModule() != 'FTS3' ) {
protected function getDB( $index ) {
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$lb = ( $this->cluster !== false )
- ? $lbFactory->getExternalLB( $this->cluster, $this->wiki )
+ ? $lbFactory->getExternalLB( $this->cluster )
: $lbFactory->getMainLB( $this->wiki );
return $lb->getConnectionRef( $index, [], $this->wiki );
<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Ori Livneh
+ */
+
/**
* APC-backed and APCu-backed function memoization
*
* MemoizedCallable::call( 'range', array( 5, 8 ) ); // same
* @endcode
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Ori Livneh
* @since 1.27
*/
class MemoizedCallable {
* 'rc'. If the URI contains a query string, its parameters will be parsed
* as RedisConnectionPool options.
*
- * @example
+ * @par Example:
+ * @code
* $wgRCFeeds['redis'] = array(
* 'formatter' => 'JSONRCFeedFormatter',
* 'uri' => "redis://127.0.0.1:6379/rc.$wgDBname",
* );
+ * @encode
*
* @since 1.22
*/
'filters' => [
[
'name' => 'hideliu',
- 'label' => 'rcfilters-filter-registered-label',
- 'description' => 'rcfilters-filter-registered-description',
// rcshowhideliu-show, rcshowhideliu-hide,
// wlshowhideliu
'showHideSuffix' => 'showhideliu',
) {
$conds[] = 'rc_user = 0';
},
- 'cssClassSuffix' => 'liu',
- 'isRowApplicableCallable' => function ( $ctx, $rc ) {
- return $rc->getAttribute( 'rc_user' );
- },
+ 'isReplacedInStructuredUi' => true,
],
[
'name' => 'hideanons',
- 'label' => 'rcfilters-filter-unregistered-label',
- 'description' => 'rcfilters-filter-unregistered-description',
// rcshowhideanons-show, rcshowhideanons-hide,
// wlshowhideanons
'showHideSuffix' => 'showhideanons',
) {
$conds[] = 'rc_user != 0';
},
- 'cssClassSuffix' => 'anon',
- 'isRowApplicableCallable' => function ( $ctx, $rc ) {
- return !$rc->getAttribute( 'rc_user' );
- },
+ 'isReplacedInStructuredUi' => true,
]
],
],
'name' => 'userExpLevel',
'title' => 'rcfilters-filtergroup-userExpLevel',
'class' => ChangesListStringOptionsFilterGroup::class,
- // Excludes unregistered users
- 'isFullCoverage' => false,
+ 'isFullCoverage' => true,
'filters' => [
+ [
+ 'name' => 'unregistered',
+ 'label' => 'rcfilters-filter-user-experience-level-unregistered-label',
+ 'description' => 'rcfilters-filter-user-experience-level-unregistered-description',
+ 'cssClassSuffix' => 'user-unregistered',
+ 'isRowApplicableCallable' => function ( $ctx, $rc ) {
+ return !$rc->getAttribute( 'rc_user' );
+ }
+ ],
+ [
+ 'name' => 'registered',
+ 'label' => 'rcfilters-filter-user-experience-level-registered-label',
+ 'description' => 'rcfilters-filter-user-experience-level-registered-description',
+ 'cssClassSuffix' => 'user-registered',
+ 'isRowApplicableCallable' => function ( $ctx, $rc ) {
+ return $rc->getAttribute( 'rc_user' );
+ }
+ ],
[
'name' => 'newcomer',
'label' => 'rcfilters-filter-user-experience-level-newcomer-label',
$this->registerFiltersFromDefinitions( [ $unstructuredGroupDefinition ] );
$userExperienceLevel = $this->getFilterGroup( 'userExpLevel' );
-
- $registration = $this->getFilterGroup( 'registration' );
- $anons = $registration->getFilter( 'hideanons' );
-
- // This means there is a conflict between any item in user experience level
- // being checked and only anons being *shown* (hideliu=1&hideanons=0 in the
- // URL, or equivalent).
- $userExperienceLevel->conflictsWith(
- $anons,
- 'rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global',
- 'rcfilters-filtergroup-user-experience-level-conflicts-unregistered',
- 'rcfilters-filter-unregistered-conflicts-user-experience-level'
- );
+ $registered = $userExperienceLevel->getFilter( 'registered' );
+ $registered->setAsSupersetOf( $userExperienceLevel->getFilter( 'newcomer' ) );
+ $registered->setAsSupersetOf( $userExperienceLevel->getFilter( 'learner' ) );
+ $registered->setAsSupersetOf( $userExperienceLevel->getFilter( 'experienced' ) );
$categoryFilter = $changeTypeGroup->getFilter( 'hidecategorization' );
$logactionsFilter = $changeTypeGroup->getFilter( 'hidelog' );
$wgLearnerMemberSince,
$wgExperiencedUserMemberSince;
- $LEVEL_COUNT = 3;
+ $LEVEL_COUNT = 5;
- // If all levels are selected, all logged-in users are included (but no
- // anons), so we can short-circuit.
+ // If all levels are selected, don't filter
if ( count( $selectedExpLevels ) === $LEVEL_COUNT ) {
+ return;
+ }
+
+ // both 'registered' and 'unregistered', experience levels, if any, are included in 'registered'
+ if (
+ in_array( 'registered', $selectedExpLevels ) &&
+ in_array( 'unregistered', $selectedExpLevels )
+ ) {
+ return;
+ }
+
+ // 'registered' but not 'unregistered', experience levels, if any, are included in 'registered'
+ if (
+ in_array( 'registered', $selectedExpLevels ) &&
+ !in_array( 'unregistered', $selectedExpLevels )
+ ) {
$conds[] = 'rc_user != 0';
return;
}
+ if ( $selectedExpLevels === [ 'unregistered' ] ) {
+ $conds[] = 'rc_user = 0';
+ return;
+ }
+
$tables[] = 'user';
$join_conds['user'] = [ 'LEFT JOIN', 'rc_user = user_id' ];
IDatabase::LIST_AND
);
+ $conditions = [];
+
+ if ( in_array( 'unregistered', $selectedExpLevels ) ) {
+ $selectedExpLevels = array_diff( $selectedExpLevels, [ 'unregistered' ] );
+ $conditions[] = 'rc_user = 0';
+ }
+
if ( $selectedExpLevels === [ 'newcomer' ] ) {
- $conds[] = "NOT ( $aboveNewcomer )";
+ $conditions[] = "NOT ( $aboveNewcomer )";
} elseif ( $selectedExpLevels === [ 'learner' ] ) {
- $conds[] = $dbr->makeList(
+ $conditions[] = $dbr->makeList(
[ $aboveNewcomer, "NOT ( $aboveLearner )" ],
IDatabase::LIST_AND
);
} elseif ( $selectedExpLevels === [ 'experienced' ] ) {
- $conds[] = $aboveLearner;
+ $conditions[] = $aboveLearner;
} elseif ( $selectedExpLevels === [ 'learner', 'newcomer' ] ) {
- $conds[] = "NOT ( $aboveLearner )";
+ $conditions[] = "NOT ( $aboveLearner )";
} elseif ( $selectedExpLevels === [ 'experienced', 'newcomer' ] ) {
- $conds[] = $dbr->makeList(
+ $conditions[] = $dbr->makeList(
[ "NOT ( $aboveNewcomer )", $aboveLearner ],
IDatabase::LIST_OR
);
} elseif ( $selectedExpLevels === [ 'experienced', 'learner' ] ) {
- $conds[] = $aboveNewcomer;
+ $conditions[] = $aboveNewcomer;
+ } elseif ( $selectedExpLevels === [ 'experienced', 'learner', 'newcomer' ] ) {
+ $conditions[] = 'rc_user != 0';
+ }
+
+ if ( count( $conditions ) > 1 ) {
+ $conds[] = $dbr->makeList( $conditions, IDatabase::LIST_OR );
+ } elseif ( count( $conditions ) === 1 ) {
+ $conds[] = reset( $conditions );
}
}
}
/**
* The type of the redirect (user/file/revision)
*
+ * Example value: `'user'`
+ *
* @var string $mType
- * @example 'user'
*/
protected $mType;
/**
* The identifier/value for the redirect (which id, which file)
*
+ * Example value: `'42'`
+ *
* @var string $mValue
- * @example '42'
*/
protected $mValue;
"removecredentials-invalidsubpage": "$1 не зьяўляецца слушным тыпам уліковых зьвестак.",
"removecredentials-success": "Вашыя ўліковыя зьвесткі былі выдаленыя.",
"credentialsform-provider": "Тып уліковых зьвестак:",
- "credentialsform-account": "Назва рахунку:"
+ "credentialsform-account": "Назва рахунку:",
+ "cannotlink-no-provider-title": "Няма рахункаў для далучэньня"
}
"navigation-heading": "नेविगेशन मेनू",
"errorpagetitle": "खराबी",
"returnto": "$1 पर लवटीं।",
- "tagline": "भोजपुरी {{SITENAME}} से",
+ "tagline": "{{SITENAME}} से",
"help": "मदद",
"search": "खोज",
"search-ignored-headings": " #<!-- एह लाइन के बिलकुल अइसहीं छोड़ दीं --> <pre>\n# हेडिंग जिनहन पर खोज करत समय धियान ना दिहल जाई।\n# एह हेडिंग वाला पन्ना जइसहीं सूचीबद्ध होखी, बदलाव प्रभावी हो जइहें।\n# आप एगो खाली संपादन (null edit) कइ के दुबारा सूचीकरण के लागू कर सकत बानी।\n# एकर सिंटेक्स अइसे बा कि:\n# * Everything from a \"#\" character to the end of the line is a comment.\n# * Every non-blank line is the exact title to ignore, case and everything.\nसंदर्भ\nबाहरी कड़ी\nइहो देखल जाय\n #</pre> <!-- एह लाइन के बिलकुल अइसहीं छोड़ दीं -->",
"blockedtext": "'''राउर सदस्यनाम अथवा आइ॰पी पता अवरोधित कर दिहल गईल बा ।'''\n\nअवरोध $1 द्वारा करल गईल रहल।\nअवरोध के कारण बा ''$2''\n\n* अवरोध के आरंभ: $8\n* अवरोध के समाप्ति: $6\n* अवरोधित इकाई: $7\n\nइ अवरोध के बारे में चर्चा करे खातिर रउआ $1 या केहु अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]] से संपर्क कर सकत बानी।\nअगर रउआ [[Special:Preferences|आपन वरीयता]] में वैद्य ई-मेल पता प्रविष्ट कइले होखब तबे 'इ प्रयोक्ता के ई-मेल भेजीं' वाला सुविधा के प्रयोग कर सकत बानी अउर रउआ एकर प्रयोग करे से ना रोकल गईल होखे।\nराउर हाल के आइ॰पी पता $3 ह अउर अवरोध क्रमांक #$5 ह।\nआपन कउनो भी प्रश्न में कृपया इ सब जानकारी भी शामिल करब।",
"autoblockedtext": "राउर आइ॰पी पता अपने आप अवरुद्ध हो गईल बा काहे कि एकर प्रयोग केहु अन्य सदस्य द्वारा होत रहल,\nजे $1 द्वारा अवरोधित करल गईल रहलन। \nअवरोध करे के कारण बा:\n\n:''$2''\n\n* अवरोध प्रारंभ: $8\n* अवरोध समाप्ति: $6\n* अवरोधित सदस्य: $7\n\nअवरोध के चर्चा करे खातिर रउआ $1 या केहु अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबंधक]] से संपर्क कर सकत बानी।\n\nकृपया ध्यान रहे कि यदि रउआ \"इ सदस्य के ई-मेल भेजीं\" वाला सुविधा के प्रयोग करे के चाहत बानी त राउर [[Special:Preferences|वरीयता]] में वैद्य ई-मेल पता होखे के चाहीं अउर एकर प्रयोग रउआ खातिर अवरोधित ना भईल होखे।\n\nराउर हाल के आइ॰पी पता $3 ह अउर अवरोध क्रमांक #$5 ह।\nआपन कउनो भी प्रश्न में कृपया इ सब जानकारी शामिल करब।",
"systemblockedtext": "राउर खाता या आइपी पता के मीडियाविकि द्वारा ऑटोमेटिक रूप से रोक दिहल गइल बा।\nएकरा खातिर कारण दिहल गइल बा:\n\n\n:<em>$2</em>\n\n* रोक के सुरुआत: $8\n* रोक समाप्त होखी: $6\n* रोक लगावे वाला: $7\n\nराउर वर्तमान आइपी पता $3 बा।\nअगर कौनों सवाल करीं तब ऊपर बतावल सगरी जानकारी देईं।",
- "blockednoreason": "à¤\95à¤\89नà¥\8b à¤\95ारण à¤\89लà¥\8dलà¥\87à¤\96ित नà¤\88à¤\96à¥\87",
- "whitelistedittext": "रà¤\89à¤\86 पनà¥\8dना समà¥\8dपादन à¤\95रà¥\87 à¤\96ातिर $1 à¤\95रà¥\87 à¤\95à¥\87 पड़à¥\80।",
- "confirmedittext": "सà¤\82पादन à¤\95रà¥\87 सà¥\87 पहिलà¥\87 à¤\86पà¤\95à¥\87 à¤\85ापना à¤\88-मà¥\87ल पता पà¥\8dरमाणित à¤\95रावल à¤\9cरà¥\81रà¥\80 बा।\nà¤\95à¥\83पया à¤\86पन [[Special:Preferences|राà¤\89र पसनà¥\8dद]] मà¥\87à¤\82 à¤\9cाà¤\95à¥\87 à¤\85ापन à¤\88-मà¥\87ल पता दिहà¥\80à¤\82 à¤\85à¤\89र à¤\89के प्रमाणित करीं।",
- "nosuchsectiontitle": "à¤\96णà¥\8dड ना मिल सà¤\95ल।",
- "nosuchsectiontext": "à¤\86प à¤\8fà¤\97à¥\8b à¤\85à¤\87सन à¤\85नà¥\81à¤à¤¾à¤\97 à¤\95à¥\87 समà¥\8dपादन à¤\95रà¥\87 à¤\95à¥\87 पà¥\8dरयतà¥\8dन à¤\95र रहल बानà¥\80 à¤\9cवन à¤\85सà¥\8dतितà¥\8dव मà¥\87à¤\82 नà¤\87à¤\96à¥\87।\nसà¤\82à¤à¤µ बा à¤\95ि à¤\9cब à¤\86प पनà¥\8dना पढत या दà¥\87à¤\96त रहनà¥\80 तवनà¥\87 à¤\98ड़à¥\80 à¤\89 à¤\95à¥\87 à¤\85पनà¥\80 à¤\9cà¤\97ह सà¥\87 हिलावल à¤\97à¤\87ल हà¥\8bà¤\96à¥\87 या हà¤\9fा दिहल à¤\97à¤\88ल हà¥\8bà¤\88।",
+ "blockednoreason": "à¤\95वनà¥\8b à¤\95ारण नà¤\87à¤\96à¥\87 बतावल à¤\97à¤\87ल",
+ "whitelistedittext": "पनà¥\8dना पर सà¤\82पादन à¤\95रà¥\87 à¤\96ातिर $1 à¤\95रà¥\80à¤\82।",
+ "confirmedittext": "सà¤\82पादन à¤\95रà¥\87 सà¥\87 पहिलà¥\87 à¤\86पà¤\95à¥\87 à¤\86पन à¤\88मà¥\87ल पता पà¥\8dरमाणित à¤\95रावल à¤\9cरà¥\81रà¥\80 बा।\nà¤\86पन [[Special:Preferences|पसà¤\82द सà¥\87à¤\9fिà¤\82à¤\97]] मà¥\87à¤\82 à¤\9cाà¤\95à¥\87 à¤\85ापन à¤\88मà¥\87ल पता सà¥\87à¤\9f à¤\95रà¥\80à¤\82 à¤\86 à¤\93à¤\95रा के प्रमाणित करीं।",
+ "nosuchsectiontitle": "à¤\96à¤\82ड ना मिलल",
+ "nosuchsectiontext": "à¤\86प à¤\8fà¤\97à¥\8b à¤\85à¤\87सन à¤\96à¤\82ड à¤\95à¥\87 सà¤\82पादन à¤\95रà¥\87 à¤\95à¥\87 à¤\95à¥\8bसिस à¤\95 रहल बानà¥\80 à¤\9cवन मà¥\8cà¤\9cà¥\82द नà¤\87à¤\96à¥\87।\nहà¥\8b सà¤\95त बा à¤\95ि à¤\9cवना à¤\9bन à¤\86प पनà¥\8dना दà¥\87à¤\96त रहलà¥\80à¤\82 à¤\93हà¥\80 समय à¤\88 à¤\96à¤\82ड à¤\98सà¤\95ा à¤à¤¾ हà¤\9fा दिहल à¤\97à¤\87ल हà¥\8bà¤\96à¥\87।",
"loginreqtitle": "खाता में प्रवेश जरुरी बा",
"loginreqlink": "लॉग इन",
"loginreqpagetext": "रउआ अन्य पन्ना देखे खातिर $1 करे के पड़ी।",
- "accmailtitle": "गुप्त-शब्द भेजा गईल",
+ "accmailtitle": "गुप्तशब्द भेजाइल",
"accmailtext": "[[User talk:$1|$1]] खातिर एगो यंत्र जनित गुप्तशब्द $2 के भेज दिहल गइल बा। खाता में प्रवेश कइला के बाद इ '''[[Special:ChangePassword|गुप्तशब्द बदल लीं]]'' वाला पन्ना पर बदलल जा सकत बा।",
"newarticle": "(नया)",
"newarticletext": "रउआ एगो अइसन कड़ी के पन्ना के अनुसरण कइले बानी जवन अभी तक उपलब्ध नइखे।\nपन्ना बनावे खातिर, नीचे के बाकस में टाइप करे के शुरु करीं (ज्यादा जानकारी खातिर देखीं [$1 मदद पन्ना])।\nयदि रउआ अहिजा गलती से आ गइल बानी त, आपन ब्राउजर के '''बैक''' (Back) बटन दबाईं!",
"revdelete-hide-text": "संशोधन पाठ्य",
"revdelete-hide-image": "फाइल के सामग्री छुपाँईं",
"revdelete-hide-name": "टारगेट आ पैरामीटर छिपाईं",
- "revdelete-hide-comment": "साराà¤\82श समà¥\8dपादन",
+ "revdelete-hide-comment": "सà¤\82पादन साराà¤\82श",
"revdelete-hide-user": "सम्पादक के सदस्यनाम/आइ॰पी पता",
"revdelete-hide-restricted": "डेटा के अउरी सदस्य सभ की साथै साथ प्रबंधक लोगन खातिर भी ढाँप दीं",
"revdelete-radio-same": "(मत बदलीं)",
"mergehistory-from": "स्रोत पन्ना:",
"mergehistory-into": "लक्ष्य पन्ना:",
"mergehistory-list": "विलय जोग्य संपादन इतिहास",
+ "mergehistory-go": "बिलय करे जोग संपादन देखावल जाव",
"mergehistory-submit": "अवतरण विलय करीं",
"mergehistory-empty": "कौनों अवतरण विलय नइखे कइल जा सकत।",
"mergehistory-done": " $1 के $3 {{PLURAL:$3|अवतरण|अवतरण सभ}} सफलता से [[:$2]] में विलय भइल।",
"mergehistory-fail": "इतिहास विलय करे में अक्षम, पन्ना आ एकर टाइम पैरामीटर चेक करीं।",
+ "mergehistory-fail-bad-timestamp": "समयमोहर अबैध बा।",
+ "mergehistory-fail-invalid-source": "स्रोत पन्ना अबैध बा।",
+ "mergehistory-fail-invalid-dest": "गंतब्य पन्ना अबैध बा।",
+ "mergehistory-fail-no-change": "इतिहास बिलय द्वारा कवनो रिवीजन के बिलय ना भइल। पन्ना आ टाइम पैरामीटर के दोबारा जाँच करीं।",
+ "mergehistory-fail-permission": "इतिहास बिलय खातिर पर्याप्त परमीशन नइखे।",
+ "mergehistory-fail-self-merge": "स्रोत आ गंतब्य पन्ना एकही बा।",
+ "mergehistory-fail-timestamps-overlap": "स्रोत रिवीजन या त गंतब्य रिवीजन के साथे ओभरलैप करत बा या बाद में आवत बा।",
+ "mergehistory-fail-toobig": "{{PLURAL:$1|रिवीजन|रिवीजन सभ}} के $1 के सीमा से ढेर रिवीजन घसकावे के पड़ी आ एही कारण इतिहास बिलय नइखे कइल जा सकत।",
+ "mergehistory-no-source": "स्रोत पन्ना $1 मौजूद नइखे।",
+ "mergehistory-no-destination": "गंतब्य पन्ना $1 मौजूद नइखे।",
+ "mergehistory-invalid-source": "स्रोत पन्ना एगो बैध टाइटिल होखे के चाहीं।",
+ "mergehistory-invalid-destination": "गंतब्य पन्ना एगो बैध टाइटिल होखे के चाहीं।",
"mergehistory-autocomment": "[[:$1]] के [[:$2]] में विलय कइल गइल",
"mergehistory-comment": "[[:$1]] के [[:$2]] में विलय कइल गइल: $3",
"mergehistory-same-destination": "स्रोत आ लक्ष्य पन्ना एकही ना होखे सकत बा",
"mergelogpagetext": "एक पन्ना इतिहास के दुसर पन्ना इतिहास में तुरंत विलय भइले के एगो सूची नीचे दिहल बा।",
"history-title": "''$1'' के संशोधन इतिहास",
"difference-title": "\"$1\" की अवतरण में अंतर",
+ "difference-title-multipage": "\"$1\" आ \"$2\" पन्ना सभ के बीच अंतर",
+ "difference-multipage": "(पन्नवन के बीच अंतर)",
"lineno": "लाइन $1:",
"compareselectedversions": "चुनल गइल संशोधन में अंतर देखीं",
"showhideselectedversions": "चुनल गइल संशोधन के दृश्यता बदलीं",
"editundo": "वापस लीं",
+ "diff-empty": "(कौनों अंतर नइखे)",
"diff-multi-sameuser": "(एही सदस्य द्वारा कइल {{PLURAL:$1|बीच के एगो बदलाव|बीच के $1 बदलाव}} नइखे देखावल जात)",
"searchresults": "खोज परिणाम",
"searchresults-title": "$1 खातिर खोज परिणाम",
"search-section": "(खंड $1)",
"search-category": "(श्रेणी $1)",
"search-suggest": "का राउर मतलब बा: $1",
+ "search-rewritten": "$1 खातिर रिजल्ट। एकरे जगह $2 खातिर खोज करीं।",
"search-interwiki-caption": "साथी प्रोजेक्ट सभ से रिजल्ट",
"search-interwiki-default": "$1 से परिणाम:",
"search-interwiki-more": "(अउर)",
"powersearch-togglenone": "कउनो ना",
"search-external": "बाहरी खोज",
"preferences": "वरीयता",
- "mypreferences": "हमार सेटिंग",
- "prefs-edits": "सम्पादन संख्या",
- "prefsnologintext2": "आपन वरीयता में बदलाव लावे खातिर प्रवेश करीं।",
- "prefs-skin": "त्वचा",
- "skin-preview": "पूर्वावलोकन",
- "datedefault": "वरीयता नईखे",
- "prefs-user-pages": "सदस्य पन्ना",
+ "mypreferences": "पसंदसेटिंग",
+ "prefs-edits": "संपादन संख्या",
+ "prefsnologintext2": "आपन पसंदसेटिंग बदले खातिर खाता में प्रवेश करीं।",
+ "prefs-skin": "स्किन",
+ "skin-preview": "झलक",
+ "datedefault": "कौनो खास पसंद नइखे",
+ "prefs-labs": "लैब्स के चीज",
+ "prefs-user-pages": "प्रयोगकर्ता पन्ना",
"prefs-personal": "प्रयोगकर्ता प्रोफाइल",
"prefs-rc": "हाल के बदलाव",
"prefs-watchlist": "धियानसूची",
"prefs-editwatchlist": "धियानसूची संपादन",
- "prefs-editwatchlist-label": "à¤\85पनà¥\80 धियानसà¥\82à¤\9aà¥\80 à¤\95à¥\87 à¤\9aà¥\80à¤\9c संपादित करीं:",
- "prefs-editwatchlist-edit": "à¤\85पनà¥\80 धियानसà¥\82à¤\9aà¥\80 à¤\95à¥\87 टाइटिल देखीं आ हटाईं",
+ "prefs-editwatchlist-label": "à¤\86पन धियानसà¥\82à¤\9aà¥\80 मà¥\87à¤\82 सामिल à¤\8fà¤\82à¤\9fà¥\8dरà¥\80 संपादित करीं:",
+ "prefs-editwatchlist-edit": "à¤\86पन धियानसà¥\82à¤\9aà¥\80 मà¥\87à¤\82 सामिल टाइटिल देखीं आ हटाईं",
"prefs-editwatchlist-raw": "टटका धियानसूची संपादित करीं",
"prefs-editwatchlist-clear": "आपन धियानसूची साफ करीं",
"prefs-watchlist-days": "धियानसूची में देखावे खातिर दिन",
"restoreprefs": "सगरी डिफाल्ट सेटिंग पहिले जइसन करीं (सगरी खंड में)",
"prefs-editing": "संपादन",
"searchresultshead": "खोज",
+ "stub-threshold": "आधार कड़ी फारमेटिंग($1) खातिर थ्रेशोल्ड:",
"stub-threshold-sample-link": "नमूना",
"stub-threshold-disabled": "अक्षम",
- "recentchangesdays": "हाल मà¥\87à¤\82 à¤à¤\87ल परिवरà¥\8dतन में देखावे खातिर दिन:",
+ "recentchangesdays": "हाल à¤\95à¥\87 बदलाव में देखावे खातिर दिन:",
"recentchangesdays-max": "अधिकतम $1{{PLURAL:$1|दिन}}",
"recentchangescount": "डिफाल्ट में देखावे खातिर संपादन संख्या:",
- "prefs-help-recentchangescount": "à¤\8fमà¥\8dमà¥\87à¤\82 हाल मà¥\87à¤\82 à¤à¤\87ल परिवरà¥\8dतन, पनà¥\8dना इतिहास, आ लॉग सब बाटे।",
+ "prefs-help-recentchangescount": "à¤\8fमà¥\8dमà¥\87à¤\82 हाल मà¥\87à¤\82 à¤à¤\87ल बदलाव, पनà¥\8dना à¤\95à¥\87 इतिहास, आ लॉग सब बाटे।",
"savedprefs": "राउर वरीयताएँ सुरक्षित कर दिहल गईल।",
"timezonelegend": "समय जोन:",
"localtime": "लोकल समय:",
"userrights-user-editname": "प्रयोगकर्ता नाँव लिखीं:",
"editusergroup": "प्रयोगकर्ता मंडली लोड करीं",
"editinguser": "अधिकार बदलाव {{GENDER:$1|प्रयोगकर्ता}}<strong>[[User:$1|$1]]</strong> $2",
+ "viewinguserrights": "प्रयोगकर्ता अधिकार देखावल जात बा:{{GENDER:$1|प्रयोगकर्ता}} <strong>[[User:$1|$1]]</strong> $2",
+ "userrights-editusergroup": "{{GENDER:$1|प्रयोगकर्ता}} मंडली संपादित करीं",
+ "userrights-viewusergroup": "{{GENDER:$1|प्रयोगकर्ता}} मंडली देखीं",
+ "saveusergroups": "{{GENDER:$1|प्रयोगकर्ता}} मंडली सहेजीं",
+ "userrights-groupsmember": "सदस्यता हासिल बा:",
+ "userrights-groupsmember-auto": "निहित सदस्यता हासिल बा:",
+ "userrights-groups-help": "ई प्रयोगकर्ता कवना मंडली में रहिहें ई चीज आप बदल सकत बानी:\n* सही के निसान वाला बक्सा के मतलब बा एह मंडली में ई शामिल बाने।\n* बिना सही के निसान वाला बक्सा के मतलब बा एह मंडली में ई शामिल नइखें।\n* एक ठो * के चीन्हा अइसन अधिकार के सूचित करे ला जवना के आप एक बेर दे देइब त हटा नइखीं सकत, या एकरे ठीक उल्टा भी।\n* एक ठो # के चीन्हा सूचित करे ला कि एह मंडली के सदस्यता के खतम होखे के समय आप पाछे (बाद में) क सकत बानी लेकिन आगे नइखीं ले आ सकत।",
"userrights-reason": "कारण:",
- "group": "मंडली (ग्रुप):",
+ "userrights-no-interwiki": "अन्य विकि सभ पर सदस्य मंडली के संपादन करे खातिर रउवाँ लगे परमीशन नइखे।",
+ "userrights-changeable-col": "जवन मंडली आप बदल सकत बानी",
+ "userrights-unchangeable-col": "जवन मंडली आप नइखीं बदल सकत",
+ "userrights-expiry-current": "$1 के खतम होखी",
+ "userrights-expiry-none": "एक्सपायर ना होखी",
+ "userrights-expiry": "एक्सपायर हो जाई:",
+ "userrights-expiry-existing": "वर्तमान में एकरा एक्सपायर होखे के टाइम बा: $3, $2",
+ "userrights-expiry-othertime": "अन्य समय:",
+ "userrights-expiry-options": "1 दिन:1 दिन,1 हप्ता:1 हप्ता,1 महीना:1 महीना,3 महीना:3 महीना,6 महीना:6 महीना,1 बरिस:1 बरिस",
+ "userrights-invalid-expiry": "मंडली \"$1\" खातिर एक्सपायरी समय अबैध बा।",
+ "group": "मंडली:",
"group-user": "सदस्य",
- "group-autoconfirmed": "à¤\96à¥\81द परà¥\80à¤\95à¥\8dषित सदसà¥\8dय",
+ "group-autoconfirmed": "सà¥\8bतà¤\83परमाणित पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता",
"group-bot": "बॉट",
"group-sysop": "प्रबंधक",
"group-bureaucrat": "ब्यूरोक्रेट",
"group-suppress": "सप्रेसर",
"group-all": "(सब)",
"group-user-member": "{{GENDER:$1|सदस्य}}",
- "group-autoconfirmed-member": "{{GENDER:$1|à¤\96à¥\81द à¤\85सà¥\8dथापित सदसà¥\8dय}}",
+ "group-autoconfirmed-member": "{{GENDER:$1|सà¥\8bतà¤\83परमाणित पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता}}",
"group-bot-member": "{{GENDER:$1|बॉट}}",
"group-sysop-member": "{{GENDER:$1|प्रबंधक}}",
"group-bureaucrat-member": "{{GENDER:$1|प्रशासक}}",
"group-suppress-member": "{{GENDER:$1|सप्रेस}}",
"grouppage-user": "{{ns:project}}:सदस्य सभ",
- "grouppage-autoconfirmed": "{{ns:project}}:à¤\96à¥\81द à¤\85सà¥\8dथापित सदसà¥\8dय सà¤",
+ "grouppage-autoconfirmed": "{{ns:project}}:सà¥\8bतà¤\83परमाणित पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता",
"grouppage-bot": "{{ns:project}}:बॉट सभ",
"grouppage-sysop": "{{ns:project}}:प्रबंधक सभ",
"grouppage-bureaucrat": "{{ns:project}}:प्रशासक सभ",
"right-createpage": "पन्ना बनाईं (बातचीत पन्ना की अलावा)",
"right-createtalk": "बातचीत पन्ना बनाईं",
"right-createaccount": "नया सदस्य खाता बनाईं",
- "right-minoredit": "à¤\9bà¥\8bà¤\9f सà¤\82पादन चिह्नित करीं",
+ "right-minoredit": "सà¤\82पादन à¤\9bà¥\8bà¤\9f चिह्नित करीं",
"right-move": "पन्ना स्थानांतरण करीं",
"right-move-subpages": "पन्नवन के उनहन की उपपन्नवन की संघे स्थानांतरित करीं",
"right-move-rootuserpages": "मूल (root) सदस्य पन्नवन के स्थानांतरित करीं",
"right-movefile": "फाइल सब स्थानांतरित करीं",
"right-suppressredirect": "स्थानांतरण करत घरी मूल पन्ना से पुनर्निदेश मत बनाईं",
"right-upload": "फाइल अपलोड करीं",
- "right-reupload": "पà¥\81रान फाà¤\87ल à¤\95à¥\80 à¤\8aपर नया लादीं",
- "right-reupload-own": "खुदे लादल फाइल पर नया फाइल लादीं",
- "right-reupload-shared": "लà¥\8bà¤\95ल मà¥\87à¤\82 साà¤\9dा मà¥\80डिया à¤à¤£à¥\8dडार à¤\95à¥\87 फाà¤\87ल सठà¤\95à¥\87 ओवरराइड करीं",
+ "right-reupload": "मà¥\8cà¤\9cà¥\82द फाà¤\87ल पर à¤\93à¤à¤°à¤°à¤¾à¤\87à¤\9f à¤\95रीं",
+ "right-reupload-own": "खुद के अपलोड कइल फाइल ओभरराइट करीं",
+ "right-reupload-shared": "साà¤\9dा मà¥\80डिया à¤à¤\82डार à¤\95à¥\87 फाà¤\87ल सठà¤\95à¥\87 लà¥\8bà¤\95ल ओवरराइड करीं",
"right-upload_by_url": "यूआरयल से फाइल अपलोड करीं",
"right-purge": "बिना पुछले कौनों पन्ना के साइट कैश के फिर लोड करीं",
- "right-autoconfirmed": "आइ पी आधारित रेट के सीमा से प्रभावित ना होखे",
+ "right-autoconfirmed": "आइपी-आधारित रेट सीमा से ना परभावित",
"right-bot": "ऑटोमेटेड प्रोसेस मानल जाय",
"right-writeapi": "API लेखन के इस्तेमाल",
"right-delete": "पन्ना हटाईं",
"action-movefile": "ई फाइल स्थानांतरित करीं",
"action-upload": "इ फाइल अपलोड करीं",
"action-reupload": "पहिले से मौजूद ए फाइल पर दूसर लादीं",
- "action-delete": "ई पन्ना के मिटाईं",
+ "action-delete": "ए पन्ना के मिटाईं",
+ "action-deleterevision": "रिवीजन मेटाईं",
+ "action-deletelogentry": "लॉग के एंट्री मेटाईं",
"action-unwatchedpages": "ध्यानसूची में जवन पन्ना नइखे ओकर सूची देखीं",
"enhancedrc-history": "इतिहास",
"recentchanges": "हाल के बदलाव",
"ancientpages": "सबसे पुरान संशोधन वाला पन्ना",
"move": "स्थानांतरण",
"movethispage": "एह पन्ना के स्थानांतरण करीं",
- "suppress": "à¤\93वरसाà¤\87à¤\9fर",
+ "suppress": "सपà¥\8dरà¥\87स",
"apihelp": "एपीआइ (API) मदद",
"apihelp-no-such-module": "मॉड्युल $1 ना मिलल।",
"booksources": "किताबी स्रोत",
"oct": "Pthi",
"nov": "Ptht",
"dec": "Pthr",
- "pagecategories": "{{PLURAL:$1|Atëkthok|Atëkthuɔk}}",
- "category_header": "Apääm në atëkthok \"$1\"ic",
- "subcategories": "Tëktëëkkor",
+ "pagecategories": "{{PLURAL:$1|bekätakthook|bekätakthuɔk}}",
+ "category_header": "Apääm në bekätakthook \"$1\"ic",
+ "subcategories": "Bekätakthuɔkkor",
"category-media-header": "Kuat në bekätakthook $1 yic",
- "hidden-categories": "{{PLURAL:$1|Atëkthok cï thiaan|Atëkthuɔk cï thiaan}}",
- "category-subcat-count": "{{PLURAL:$2|Bekätakthookë anɔŋ bekätakthookthiikɛ̈ kepɛ̈c.|Akuutkäŋë anɔŋ \n{{PLURAL:$1|bekätakthookë|$1 bekäŋtakthookkɛ̈}}, në $2 yic̈;}}",
+ "hidden-categories": "{{PLURAL:$1|Bekätakthook cï thiaan|Bekätakthuɔk cï thiaan}}",
+ "category-subcat-count": "{{PLURAL:$2|Bekätakthookë anɔŋ bekätakthookkorkɛ̈ kepɛ̈c.|Bekätakthookë anɔŋ {{PLURAL:$1|bekätakthookkorë|$1 bekätakthuɔkkorkɛ̈}}, në $2 yic̈;}}",
"category-article-count": "{{PLURAL:$2|Bekätakthookë anɔŋic yärë yetök.|{{PLURAL:$1|Yärë atɔ̈|$1 yɔ̈rkɛ̈ aatɔ̈}} bekätakthook thiöökë yic, në $2 yic.}}",
"category-file-count": "{{PLURAL:$2|Bekätakthook kän anɔŋic wëtmät kän etök.|{{PLURAL:|Wëtmät de $1 thiöökë atɔ̈ |wëlmäät ke $1 thiookkɛ̈ aa tɔ̈}} në bekätakthook känic, në $2 yiic ëbɛ̈n.}}",
"listingcontinuesabbrev": "ɣäthtueŋ",
"nstab-project": "Apam kälooi",
"nstab-image": "Apamduööt",
"nstab-template": "Macuëc",
- "nstab-category": "Atëkthok",
+ "nstab-category": "Bekätakthook",
"mainpage-nstab": "Apam këdït",
"badtitle": "Rin awäc",
"badtitletext": "Këjiɛmë ca thiëëcë acïï lɔcök, tëdɛ̈ ka cïn kë tɔ̈u thïn, tëdɛ̈ ka këjiɛmë de thuɔkmɛ̈t wälä de wikimɛ̈t aa këcëkɛ nyiɛc nuet apath. Tëkdɛ̈ kä nɔŋic cït cïï lëu bïke luööi në käjiɛmëkeyiic.",
"templatesused": "{{PLURAL:$1|Macuëc|Mïcuëc}} ee luööi në apam känic",
"template-protected": "(cïtiit)",
"template-semiprotected": "(gëlamääth)",
- "hiddencategories": "Apamkën ee rem ë {{PLURAL:$1|1 bekätakthook cï thiaan |$1 bekäŋtakthook cï thiaan}}:",
- "permissionserrorstext-withaction": "Yïn acïï nɔŋ nhomlääu ba $2, \n{{PLURAL:$1|wɛ̈t de kän|wët de käk}}:",
+ "hiddencategories": "Apamkën ee rem ë {{PLURAL:$1|1 bekätakthook cï thiaan |$1 bekätakthuɔk cï thiaan}}:",
+ "permissionserrorstext-withaction": "Yïn acïï nɔŋ nhomlääu ba $2, {{PLURAL:$1|wɛ̈t de kän|wët de käk}}:",
"moveddeleted-notice": "Apam acï cuɔthwei. Athörtɔ̈ɔ̈u de cothëwei ku nyiɛɛi në apamë aa cïke gam piiny ëtɛ̈n tɔŋ raan wïc bë ke kueen",
"content-model-javascript": "JavaScript",
"viewpagelogs": "Ɣoi athörtɔ̈ɔ̈u në apamkën",
"logeventslist-submit": "Nyooth",
"allarticles": "Abɛ̈ɛ̈k ëbɛ̈n",
"allpagessubmit": "Lɔ",
- "categories": "Atëkthuɔk",
+ "categories": "Bekätakthuɔk",
"categories-submit": "Nyooth",
"sp-deletedcontributions-contribs": "amöc",
"linksearch-ns": "Rinɣɔnläu",
"tooltip-ca-nstab-project": "Ɣoi apam kätɔ̈",
"tooltip-ca-nstab-image": "Ɣoië apäm ë makec",
"tooltip-ca-nstab-template": "Tïŋ macuëc",
- "tooltip-ca-nstab-category": "Ɣoië apäm atëkthok",
+ "tooltip-ca-nstab-category": "Ɣoië apäm bekätakthook",
"tooltip-save": "Tɔ̈ɔ̈uë weerdu",
"tooltip-preview": "Tiɛ̈ŋë tueŋ weerdu. Yïn looië yen këcë guor tɔ̈ɔ̈u.",
"tooltip-diff": "Nyoothë weer ɣo cä looi këcïgɔ̈tic",
"exif-colorspace": "Tëlääu kiit",
"exif-datetimeoriginal": "Akölnïn ku akölic ë cäk ë akutëyith",
"exif-datetimedigitized": "Akölnïn ku akölic ë cɔkakuënnhialkupiny",
- "exif-iimcategory": "Atëkthok",
+ "exif-iimcategory": "Bekätakthook",
"exif-disclaimer": "Acëkakuɔ",
"exif-orientation-1": "Epath",
"namespacesall": "ëbɛ̈n",
"rcfilters-invalid-filter": "Invalid filter",
"rcfilters-empty-filter": "No active filters. All contributions are shown.",
"rcfilters-filterlist-title": "Filters",
- "rcfilters-filterlist-whatsthis": "What's this?",
+ "rcfilters-filterlist-whatsthis": "How do these work?",
"rcfilters-filterlist-feedbacklink": "Provide feedback on the new (beta) filters",
"rcfilters-highlightbutton-title": "Highlight results",
"rcfilters-highlightmenu-title": "Select a color",
"rcfilters-noresults-conflict": "No results found because the search criteria are in conflict",
"rcfilters-state-message-subset": "This filter has no effect because its results are included with those of the following, broader {{PLURAL:$2|filter|filters}} (try highlighting to distinguish it): $1",
"rcfilters-state-message-fullcoverage": "Selecting all filters in a group is the same as selecting none, so this filter has no effect. Group includes: $1",
- "rcfilters-filtergroup-registration": "User registration",
- "rcfilters-filter-registered-label": "Registered",
- "rcfilters-filter-registered-description": "Logged-in editors.",
- "rcfilters-filter-unregistered-label": "Unregistered",
- "rcfilters-filter-unregistered-description": "Editors who aren’t logged in.",
- "rcfilters-filter-unregistered-conflicts-user-experience-level": "This filter conflicts with the following Experience {{PLURAL:$2|filter|filters}}, which {{PLURAL:$2|finds|find}} only registered users: $1",
"rcfilters-filtergroup-authorship": "Contribution authorship",
"rcfilters-filter-editsbyself-label": "Changes by you",
"rcfilters-filter-editsbyself-description": "Your own contributions.",
"rcfilters-filter-editsbyother-label": "Changes by others",
"rcfilters-filter-editsbyother-description": "All changes except your own.",
- "rcfilters-filtergroup-userExpLevel": "Experience level (for registered users only)",
- "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Experience filters find only registered users, so this filter conflicts with the “Unregistered” filter.",
- "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "The \"Unregistered\" filter conflicts with one or more Experience filters, which find registered users only. The conflicting filters are marked in the Active Filters area, above.",
+ "rcfilters-filtergroup-userExpLevel": "Experience registration and experience",
+ "rcfilters-filter-user-experience-level-registered-label": "Registered",
+ "rcfilters-filter-user-experience-level-registered-description": "Logged-in editors.",
+ "rcfilters-filter-user-experience-level-unregistered-label": "Unregistered",
+ "rcfilters-filter-user-experience-level-unregistered-description": "Editors who aren't logged-in.",
"rcfilters-filter-user-experience-level-newcomer-label": "Newcomers",
- "rcfilters-filter-user-experience-level-newcomer-description": "Fewer than 10 edits and 4 days of activity.",
+ "rcfilters-filter-user-experience-level-newcomer-description": "Registered editors with fewer than 10 edits and 4 days of activity.",
"rcfilters-filter-user-experience-level-learner-label": "Learners",
- "rcfilters-filter-user-experience-level-learner-description": "More experience than \"Newcomers\" but less than \"Experienced users\".",
+ "rcfilters-filter-user-experience-level-learner-description": "Registered editors whose experience falls between \"Newcomers\" and \"Experienced users.\"",
"rcfilters-filter-user-experience-level-experienced-label": "Experienced users",
- "rcfilters-filter-user-experience-level-experienced-description": "More than 30 days of activity and 500 edits.",
+ "rcfilters-filter-user-experience-level-experienced-description": "Registered editors with more than 500 edits and 30 days of activity.",
"rcfilters-filtergroup-automated": "Automated contributions",
"rcfilters-filter-bots-label": "Bot",
"rcfilters-filter-bots-description": "Edits made by automated tools.",
"rcfilters-tag-prefix-namespace": ":$1",
"rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
"rcfilters-tag-prefix-tags": "#$1",
+ "rcfilters-exclude-button-off": "Exclude selected",
+ "rcfilters-exclude-button-on": "Excluding selected",
"rcfilters-view-tags": "Tagged edits",
"rcfilters-view-namespaces-tooltip": "Filter results by namespace",
"rcfilters-view-tags-tooltip": "Filter results using edit tags",
"undelete-search-title": "Ezabatutako orrialdeak bilatu",
"undelete-search-box": "Ezabatutako orrialdeak bilatu",
"undelete-search-prefix": "Honela hasten diren orrialdeak erakutsi:",
+ "undelete-search-full": "Orrialde izenburuak erakutsi:",
"undelete-search-submit": "Bilatu",
"undelete-no-results": "Ez da bat datorren orrialderik aurkitu ezabaketen artxiboan.",
"undelete-filename-mismatch": "Ezin da $1 denbora-marka duten fitxategi aldaketa ezabatua berrezarri: fitxategi-izena ez dator bat",
"printableversion": "Sufar bugawa",
"permalink": "Dawwamammen mahaɗi",
"print": "Buga",
+ "view": "Duba",
"edit": "Gyarawa",
"create": "Ƙirƙira",
"delete": "Soke",
"showdiff": "Nuna sauye-sauye",
"anoneditwarning": "'''Hattara:''' Ba ku yi logi ba.\nZa a rubuta adireshinku na IP a cikin tarihin sauye-sauyen wannan shafi.",
"summary-preview": "Rigya-gani na taƙaici:",
+ "loginreqlink": "Shiga",
"newarticle": "(Sabo)",
"newarticletext": "Kun latsa mahaɗi zuwa shafin da babu shi tukuna.\nDomin ƙirƙiro wannan shafin, ku fara rubutu a cikin fage na ƙasa (duba [$1 shafin taimako] don ƙarin bayani).\nIdan kun ɓata ne cikin shawaginku, to ku latsa maɓallin '''baya''' na safuwayan shawaginku.",
"noarticletext": "A halin yanzu babu matani a kan wannan shafi.\nKuna iya [[Special:Search/{{PAGENAME}}|nemo kan wannan shafi]] cikin wasu shafuna,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} bincika rajistan ayyukan],\nko [{{fullurl:{{FULLPAGENAME}}|action=edit}} gyara wannan shafi]</span>.",
"prevn": "baya {{PLURAL:$1|$1}}",
"nextn": "gaba {{PLURAL:$1|$1}}",
"viewprevnext": "Duba ($1 {{int:pipe-separator}} $2) ($3)",
+ "searchprofile-everything": "Duk abin da",
"search-result-size": "$1 ({{PLURAL:$2|1 kalma|$2 kalmomi}})",
"search-redirect": "(turawa daga $1)",
"search-section": "(sashe $1)",
"rightslog": "Rajistan bayar da izini ga ma'aikata",
"action-edit": "gyara wannan shafi",
"nchanges": "{{PLURAL:$1|sauyi|sauye-sauye}} $1",
+ "enhancedrc-history": "Tarihi",
"recentchanges": "Sauye-sauyen baya-bayan nan",
"recentchanges-legend": "Zaɓi na sauye-sauyen baya-bayan nan",
"recentchanges-feed-description": "Bi sawun sauye-sauyen ƙarshe na wikin da ke cikin wannan kwarare",
+ "recentchanges-label-minor": "Karamin gyara ne",
"rclistfrom": "Nuna sabbin sauye-sauye tun daga $3 $2",
"rcshowhideminor": "$1 ƙananen sauye-sauye",
"rcshowhidebots": "Rabuwat $1",
+ "rcshowhidebots-show": "Nuna",
"rcshowhideliu": "$1 Ma'aikata logaggi",
"rcshowhideanons": "$1 ma'aikata masu ɓoyayye suna",
"rcshowhidemine": "$1 sauye-sauyena",
"tooltip-search": "Binciko {{SITENAME}}",
"tooltip-search-go": "A je ga shafi mai wannan suna idan akwai shi",
"tooltip-search-fulltext": "Binciki shafuna masu wannan matani",
+ "tooltip-p-logo": "Duba babban shafin",
"tooltip-n-mainpage": "Duba shafin Marhabin",
"tooltip-n-mainpage-description": "Duba shafin marhabin",
"tooltip-n-portal": "A game da wannan shiri, abinda za a iya yi, ina za a samu abubuwa",
"anontalk": "Дувца оттадар",
"navigation": "Навигаци",
"and": " а",
- "qbfind": "Лахар",
- "qbbrowse": "БIаргтохар",
- "qbedit": "Нийсде",
- "qbpageoptions": "ОагIон оттамаш",
- "qbmyoptions": "Хьа гIирсаш тоаяраш",
"faq": "КТХ",
- "faqpage": "Project:КТХ",
"actions": "Ардамаш",
"namespaces": "ЦIерий аренаш",
"variants": "Варианташ",
"edit-local": "Хувца локальни йоазонца сурт оттадар",
"create": "Хьакхолла",
"create-local": "ТIатоха локальни йоазонца сурт оттадар",
- "editthispage": "Нийсъе ер оагIув",
- "create-this-page": "Хьакхолла ер оагӀув",
"delete": "ДӀаяккха",
- "deletethispage": "ДӀаяккха ер оагӀув",
- "undeletethispage": "Юхаметтаоттае ер оагӀув",
"undelete_short": "Юхаметтаоттде {{PLURAL:$1|$1 нийсдар|$1 нийсдараш}}",
"viewdeleted_short": "{{PLURAL:$1|$1 дIадаьккха нийсдарга|дIадаьккха нийсдарга|$1 дIадаьккха нийсдарашга}} хьажар",
"protect": "ГIо де",
"protect_change": "хувца",
- "protectthispage": "ГIо (лорадар) де укх оагIон",
"unprotect": "ГIо хувца",
- "unprotectthispage": "Укх оагIон гIо (лорадар) хувца",
"newpage": "Керда оагӀув",
- "talkpage": "Ер оагIув ювца",
"talkpagelinktext": "дувца оттадар",
"specialpage": "ГIулакха оагӀув",
"personaltools": "Доакъашхочун гӀирсаш",
- "articlepage": "БIаргтоха оагIонга",
"talk": "Дувца оттадар",
"views": "Хьажараш",
"toolbox": "ГӀирсаш",
- "userpage": "Доакъашхочун оагIон бIаргтоха",
- "projectpage": "Проекта оагIон бIаргтоха",
"imagepage": "Файла оагIон бIаргтоха",
"mediawikipage": "Хьахьокха хоам бара оагIув",
"templatepage": "Лера оагIон бIаргтоха",
"redirectedfrom": "($1 дIа-сахьожаяьй укхаз)",
"redirectpagesub": "ОагIув-дIа-сахьожадар",
"redirectto": "ДIа-сахьожадар укхаза:",
- "lastmodifiedat": "УкÑ\85 оагIoн Ñ\82IеÑ\85Ñ\85Ñ\8cаÑ\80а Ñ\85Ñ\83вÑ\86ам: $2, $1.",
+ "lastmodifiedat": "Ð\95Ñ\80 оагIÑ\83в Ñ\82IеÑ\85Ñ\85Ñ\8cаÑ\80а Ñ\85ийÑ\86а Ñ\85иннай $2 $1 Ñ\8fÑ\8cннаÑ\87а Ñ\85аÌ\81на.",
"viewcount": "Укх оагIонга хьежа хиннаб $1{{PLURAL:$1|-зза}}.",
"protectedpage": "ГIо оттадаь лораяь оагIув",
"jumpto": "Дехьавала укхаза:",
"noarticletext-nopermission": "ХIанз укх оагӀон тӀа текст яц.\nШун аьттув ба [[Special:Search/{{PAGENAME}}|цу тайпара цӀи белгалъяр хьалаха]] кхыйола оагIонаш тIа, иштта\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тара дола тептарай дIаяздаьраш].</span> Ер оагӀув хьакхолла Хьа бокъо яц.",
"note": "'''Белгалдоахар:'''",
"previewnote": "'''Теркам бе, ер хьалххе бIаргтохар мара бац.'''\nХьа хувцамаш хIанза а дIаяздаь дац!",
+ "continue-editing": "Хувцар кхы дIахо де",
"editing": "Хувцам: $1",
"creating": "«$1» оагIув хьакхоллар",
"editingsection": "Хувцам: $1 (оагӀон дáкъа)",
"page_first": "цхьоаллагIа",
"page_last": "тӀехьара",
"histlegend": "Версий хоржам: белгалъе шун вIаши йиста безам бола оагIон версеш, тIаккха тоIае '''{{int:compare-submit}}'''.<br />\nКхетавар: '''({{int:cur}})''' — карара версеца дола башхалонаш; '''({{int:last}})''' — хьалха йоагIаш версеца дола башхалонаш; '''{{int:minoreditletter}}''' — зIамига хувцамаш.",
- "history-fieldset-title": "Ð\98Ñ\81Ñ\82оÑ\80ена бIаÑ\80гÑ\82оÑ\85а",
+ "history-fieldset-title": "Ð\94аÑ\8c Ñ\85инна Ñ\85Ñ\83вÑ\86амаÑ\88 лаÑ\85аÑ\80",
"history-show-deleted": "Алхха дӀадаьккхараш",
"histfirst": "эггара къаьнагIа",
"histlast": "эггара кердагIа",
"lineno": "МугI $1:",
"compareselectedversions": "ВIаши йиста хержа версеш",
"editundo": "юхадаккха",
+ "diff-empty": "(башхалонаш яц)",
"diff-multi-sameuser": "({{PLURAL:$1|цхьа юкъ хулаш йола верси|$1 юкъ хулаш йола версеш}} гуш яц цу доакъашхочун)",
"searchresults": "Лахар чакхдоалаш корадаьр",
"searchresults-title": "«$1» лахар",
"nextn-title": "{{PLURAL:$1|ТIадоагIа $1 яздар|ТIадоагIа $1 яздараш}}",
"shown-title": "Гойта $1 {{PLURAL:$1|яздаьр|яздаьраш}} укх оáгIон тIа",
"viewprevnext": "ДIахьажа ($1 {{int:pipe-separator}} $2) ($3)",
- "searchmenu-exists": "<strong>Укх вики чу йолаш я оагӀув «[[:$1]]».</strong>",
+ "searchmenu-exists": "'''Укх вики чу йолаш я оагӀув «[[:$1]]».'''",
"searchmenu-new": "<strong>Хьакхолла оагIув «[[:$1]]» укх вики-проекте!</strong>\n{{PLURAL:$2|0=|Иштта хьажа Iайха лийха оагIонга.|Иштта хьажа хьай лахара хьахиннарашка.}}",
"searchprofile-articles": "Кертера оагIонаш",
"searchprofile-images": "Мультимедиа",
"nolinkstoimage": "Укх файла тIахьожавеш йола оагIонаш яц.",
"sharedupload": "Ер файл $1 чура я, из пайда эцаш лелае мегаш я кхыйола проекташ чу.",
"sharedupload-desc-here": "Ер файл $1 чура я, иштта кхыйола проекташ чу пайда эца аьттув болаш я.\nЦун [$2 сурт оттадара оагIон] хоам кIалхахь хьабоалабаьб.",
+ "filepage-nofile": "Ишта цӀи йола файл йоацаш я.",
"uploadnewversion-linktext": "Чуяккха укх файла керда верси",
"upload-disallowed-here": "Хьа бокъо яц ер файл юха дӀаязъе.",
"filerevert-comment": "Бахьан:",
"booksources-search-legend": "Джейнах лаьца хоам лахар",
"booksources-search": "Хьалáха",
"log": "Тептараш",
+ "logempty": "Укх оагӀон дӀаяздаьраш тептара чу дац.",
"allpages": "Еррига оагIонаш",
"prevpage": "Хьалха йоагIа оагIув ($1)",
"allpagesfrom": "Гучаяккха оагIонаш йолалуш йола укхох:",
"version-specialpages": "ГIулакха оагӀонаш",
"version-version": "($1)",
"version-software-version": "Верси",
+ "redirect-submit": "Дехьавала",
+ "redirect-lookup": "Лахар:",
+ "redirect-value": "Боарам:",
+ "redirect-user": "Доакъашхочун ID",
+ "redirect-page": "ОагӀон ID",
+ "redirect-revision": "ОагӀон верси",
+ "redirect-file": "Файла цӀи",
"fileduplicatesearch-filename": "Файла цӀи:",
"fileduplicatesearch-submit": "Хьалáха",
"specialpages": "ЛаьрххIа йола оагIонаш",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|새 문서 목록]]도 보세요)",
"recentchanges-legend-plusminus": "(<em>±123</em>)",
"recentchanges-submit": "보기",
+ "rcfilters-legend-heading": "<strong>약어 목록:</strong>",
"rcfilters-activefilters": "사용 중인 필터",
"rcfilters-advancedfilters": "고급 필터",
"rcfilters-quickfilters": "저장된 필터",
"rcfilters-invalid-filter": "A label for an invalid filter.",
"rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
"rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
- "rcfilters-filterlist-whatsthis": "Caption for the link that opens a popup with explanations about this filter group.",
+ "rcfilters-filterlist-whatsthis": "Caption for the link that opens a popup with explanations about this filter group, explaining what it is and how it works.",
"rcfilters-filterlist-feedbacklink": "Caption for the link to the feedback page about the filters beta feature.",
"rcfilters-highlightbutton-title": "Title for the highlight button used to toggle the highlight feature on and off.",
"rcfilters-highlightmenu-title": "Title for the highlight menu used to select the highlight color for an individual filter.",
"rcfilters-noresults-conflict": "A message displayed in the results area when no results found because there are filters in conflict with one another.",
"rcfilters-state-message-subset": "Tooltip shown when hovering over a filter tag when one or more broader filters that contain the hovered filter are also selected. This indicates that the hovered filter has no effect because all the results it matches are also matched by the broader filter(s). Parameters:\n* $1 - Comma-separated string of selected broader filters that this filter is a subset of\n* $2 - Count of filters in $1, for PLURAL",
"rcfilters-state-message-fullcoverage": "Tooltip shown when hovering over a filter tag when all the filters in its group are selected. This indicates that the hovered filter has no effect because the selected filters in the group cover all changes. Parameters:\n* $1 - Comma-separated string of selected filters in the group\n* $2 - Count of filters in $1, for PLURAL",
- "rcfilters-filtergroup-registration": "Title for the filter group for editor registration type.",
- "rcfilters-filter-registered-label": "Label for the filter for showing edits made by logged-in users.\n{{Identical|Registered}}",
- "rcfilters-filter-registered-description": "Description for the filter for showing edits made by logged-in users.",
- "rcfilters-filter-unregistered-label": "Label for the filter for showing edits made by logged-out users.\n{{Identical|Unregistered}}",
- "rcfilters-filter-unregistered-description": "Description for the filter for showing edits made by logged-out users.",
- "rcfilters-filter-unregistered-conflicts-user-experience-level": "Tooltip shown when hovering over a Unregistered filter tag, when a User Experience Level filter is also selected.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.\n\n\"Experience\" is based on {{msg-mw|Rcfilters-filtergroup-userExpLevel}}.\n\nThis indicates that no results will be shown, because users matched by the User Experience Level groups are never unregistered. Parameters:\n* $1 - Comma-separated string of selected User Experience Level filters, e.g. \"Newcomer, Experienced\"\n* $2 - Count of selected User Experience Level filters, for PLURAL",
"rcfilters-filtergroup-authorship": "Title for the filter group for edit authorship. This filter group allows the user to choose between \"Your own edits\" and \"Edits by others\". More info: https://phabricator.wikimedia.org/T149859",
"rcfilters-filter-editsbyself-label": "Label for the filter for showing edits made by the current user.",
"rcfilters-filter-editsbyself-description": "Description for the filter for showing edits made by the current user.",
"rcfilters-filter-editsbyother-label": "Label for the filter for showing edits made by anyone other than the current user.",
"rcfilters-filter-editsbyother-description": "Description for the filter for showing edits made by anyone other than the current user.",
"rcfilters-filtergroup-userExpLevel": "Title for the filter group for user experience levels.",
- "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Tooltip shown when hovering over a User Experience Level filter tag, when only Unregistered users are being shown. This indicates that no results will be shown, because users matched by the User Experience Level groups are never unregistered.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.",
- "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "Message shown in the result area when both a User Experience Level filter and the Unregistered filter are selected. This indicates that no results will be shown because users selected by the User Experience Filter are never unregistered.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.\n\n\"Experience\" is based on {{msg-mw|Rcfilters-filtergroup-userExpLevel}}.",
+ "rcfilters-filter-user-experience-level-registered-label": "Label for the filter for showing edits made by logged-in editors.",
+ "rcfilters-filter-user-experience-level-registered-description": "Description for the filter for showing edits made by logged-in editors.",
+ "rcfilters-filter-user-experience-level-unregistered-label": "Label for the filter for showing edits made by anonymous editors.",
+ "rcfilters-filter-user-experience-level-unregistered-description": "Description for the filter for showing edits made by anonymous editors.",
"rcfilters-filter-user-experience-level-newcomer-label": "Label for the filter for showing edits made by new editors.",
"rcfilters-filter-user-experience-level-newcomer-description": "Description for the filter for showing edits made by new editors.",
"rcfilters-filter-user-experience-level-learner-label": "Label for the filter for showing edits made by learning editors.",
"rcfilters-tag-prefix-namespace": "Prefix for the namespace tags in [[Special:RecentChanges]]. Namespace tags use a colon (:) as prefix. Please keep this format.\n\nParameters:\n* $1 - Filter name.",
"rcfilters-tag-prefix-namespace-inverted": "Prefix for the namespace inverted tags in [[Special:RecentChanges]]. Namespace tags use a colon (:) as prefix. Please keep this format.\n\nParameters:\n* $1 - Filter name.\n{{Identical|Not}}",
"rcfilters-tag-prefix-tags": "Prefix for the edit tags in [[Special:RecentChanges]]. Edit tags use a hash (#) as prefix. Please keep this format.\n\nParameters:\n* $1 - Tag display name.",
+ "rcfilters-exclude-button-off": "Title for the button that excludes selected namespaces, when it is not yet active.",
+ "rcfilters-exclude-button-on": "Title for the button that excludes selected namespaces, when it is not yet active.",
"rcfilters-view-tags": "Title for the tags view in [[Special:RecentChanges]]\n{{Identical|Tag}}",
"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]]",
"lockedbyandtime": "(de $1 'u $2 a le $3)",
"move-page": "Spuèste $1",
"move-page-legend": "Spuèste 'a pàgene",
- "movepagetext": "Ausanne 'u form aqquà sotte ste cange 'u nome d'a pàgene, spustanne tutte 'a storia soje sus a 'u nome nuéve.\nU' vecchie titole devènde 'nu ridirezionamende sus 'a pàgena nove.\nTu puè aggiornà 'u ridirezionamende ca apponde a 'u titole origgenale automaticamende.\nCe tu no ste scacchie, sta secure de condrollà [[Special:DoubleRedirects|doppie ridirezionaminde]] o [[Special:BrokenRedirects|ridirezionaminde scuasciate]].\nTu si 'u responsabbile de quidde ca cumbine, assicurate ca 'u collegamende condinue a appondà addò avessa scè.\n\nVide Bbuene ca 'a pàgene '''non''' g'avène spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.\nQuieste significhe ca tu puè fà turnà 'u vecchie nome 'a pàgene ce jedde ha state renomenate e t'è rese conde ca è fatte 'na studecarije sovrascrevènne 'na pàgene esistende.\n\n'''ATTENZIONE!'''\nQuiste pò essere 'nu cangiamende drastiche e inaspettate de 'na pàgene famose assaje;\npe piacere a essere secure-secure de le conseguenze apprime de condinuà.",
- "movepagetext-noredirectfixer": "Ausanne 'u module aqquà sotte puè renomenà 'na pàgene, spustanne tutte 'a storia soje sotte a 'u nome nuève.\n'U titele vecchie addevende 'na pàgene de ridirezionamende a 'u titele nuève.\nMe raccomande condrolle le redirezionaminde [[Special:DoubleRedirects|a doppie]] o [[Special:BrokenRedirects|scuasciate]].\nTu si responsabbele de assicurarte ca le collagaminde appondene a 'u punde giuste.\n\nVide ca 'a pàgene '''non''' g'avene spustate ce già stè 'na pàgene cu 'u titele nuève, a meno che non g'è vacande o jè 'nu ridirezionamende e non ge tène 'na storie de cangiaminde.\nQuiste signifeche ca jè possibbele renominà 'na pàgene accume se chiamave apprime addò tu è fatte 'n'errore e non g'è possibbele sovrascirevere 'na pàgene esistende.\n\n'''Fà Attenziò!'''\nQuiste pò essere 'nu cangiamende inaspettate pe 'na pàgene popolare;\nPe piacere ha essere secure secure de avere capite le conzeguenze apprime de scè nnande.",
+ "movepagetext": "Ausanne 'u form aqquà sotte ste cange 'u nome d'a pàgene, spustanne tutte 'a storia soje sus a 'u nome nuéve.\nU' vecchie titole devènde 'nu ridirezionamende sus 'a pàgena nove.\nTu puè aggiornà 'u ridirezionamende ca apponde a 'u titole origgenale automaticamende.\nCe tu no ste scacchie, sta secure de condrollà [[Special:DoubleRedirects|doppie ridirezionaminde]] o [[Special:BrokenRedirects|ridirezionaminde scuasciate]].\nTu si 'u responsabbile de quidde ca cumbine, assicurate ca 'u collegamende condinue a appondà addò avessa scè.\n\nVide Bbuene ca 'a pàgene <strong>non</strong> g'avène spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.\nQuieste significhe ca tu puè fà turnà 'u vecchie nome 'a pàgene ce jedde ha state renomenate e t'è rese conde ca è fatte 'na studecarije sovrascrevènne 'na pàgene esistende.\n\n<strong>ATTENZIONE!</strong>\nQuiste pò essere 'nu cangiamende drastiche e inaspettate de 'na pàgene famose assaje;\npe piacere a essere secure-secure de le conseguenze apprime de condinuà.",
+ "movepagetext-noredirectfixer": "Ausanne 'u module aqquà sotte puè renomenà 'na pàgene, spustanne tutte 'a storia soje sotte a 'u nome nuève.\n'U titele vecchie addevende 'na pàgene de ridirezionamende a 'u titele nuève.\nMe raccomande condrolle le redirezionaminde [[Special:DoubleRedirects|a doppie]] o [[Special:BrokenRedirects|scuasciate]].\nTu si responsabbele de assicurarte ca le collagaminde appondene a 'u punde giuste.\n\nVide ca 'a pàgene <strong>non</strong> g'avene spustate ce già stè 'na pàgene cu 'u titele nuève, a meno che non g'è vacande o jè 'nu ridirezionamende e non ge tène 'na storie de cangiaminde.\nQuiste signifeche ca jè possibbele renominà 'na pàgene accume se chiamave apprime addò tu è fatte 'n'errore e non g'è possibbele sovrascirevere 'na pàgene esistende.\n\n<strong>Fà Attenziò!</strong>\nQuiste pò essere 'nu cangiamende inaspettate pe 'na pàgene popolare;\nPe piacere ha essere secure secure de avere capite le conzeguenze apprime de scè nnande.",
"movepagetalktext": "Ce tu cazze sta buatte, 'A pàgene de le 'ngazzaminde associate avène spustate automaticamende, sembre ca non g'esisite 'n'otra pàgene de le 'ngazzaminde.\n\nJndr'à stu case, 'a pàgene non g'avène spustate e pò t'a cupià a màne 'u condenute sue.",
"moveuserpage-warning": "'''Attenziò:''' Tu stè spuèste 'na pàgene utende. Vide bbuène ca sulamende 'a pàgene avène spustate ma l'utende ''non'' g'avene renomenate.",
"movecategorypage-warning": "<strong>Attenziò:</strong> Tu vuè ccu spuéste 'na pàgene categorije. Vide ca sulamende 'a pàgene avène spustate ma tutte le pàggene ca stonne jndr'à categorije <em>non</em> g'avène spustate sotte a quedda nove.",
"page_last": "последња",
"histlegend": "Избор разлика: изаберите кутијице измена за упоређивање и притисните ентер или дугме на дну.<br />\nОбјашњење: <strong>({{int:cur}})</strong> = разлика с тренутном изменом, <strong>({{int:last}})</strong> = разлика с претходном изменом, <strong>{{int:minoreditletter}}</strong> = мала измена",
"history-fieldset-title": "Преглед измена",
- "history-show-deleted": "Само обÑ\80иÑ\81ано",
+ "history-show-deleted": "Само обÑ\80иÑ\81ане измÑ\98ене",
"histfirst": "најстарије",
"histlast": "најновије",
"historysize": "({{PLURAL:$1|1 бајт|$1 бајта|$1 бајтова}})",
"prefs-help-prefershttps": "Ова подешавања ће ступити на снагу при следећој пријави.",
"prefswarning-warning": "Променили сте ваша подешавања али нисте их још сачували.\nАко не притиснете „$1“ ваша подешавања ће бити изгубљена.",
"prefs-tabs-navigation-hint": "Савет: можете користити типке са левом и десном стрелицом за кретање кроз картице.",
- "userrights": "УпÑ\80авÑ\99аÑ\9aе коÑ\80иÑ\81ниÑ\87ким пÑ\80авима",
+ "userrights": "Ð\9aоÑ\80иÑ\81ниÑ\87ка пÑ\80ава",
"userrights-lookup-user": "Изабери корисника",
"userrights-user-editname": "Корисничко име:",
"editusergroup": "Учитај корисничке групе",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
"recentchanges-submit": "Прикажи",
"rcfilters-activefilters": "Активни филтери",
- "rcfilters-quickfilters": "Ð\91Ñ\80зе везе",
+ "rcfilters-quickfilters": "СаÑ\87Ñ\83вани Ñ\84илÑ\82еÑ\80и",
"rcfilters-savedqueries-defaultlabel": "Сачувани филтери",
"rcfilters-savedqueries-rename": "Преименуј",
"rcfilters-savedqueries-setdefault": "Постави као подразумевано",
"rcfilters-savedqueries-unsetdefault": "Уклони као подразумевано",
"rcfilters-savedqueries-remove": "Уклони",
"rcfilters-savedqueries-new-name-label": "Име",
- "rcfilters-savedqueries-apply-label": "Направи брзу везу",
+ "rcfilters-savedqueries-apply-label": "Направи филтер",
"rcfilters-savedqueries-cancel-label": "Откажи",
- "rcfilters-savedqueries-add-new-title": "СаÑ\87Ñ\83ваÑ\98 Ñ\84илÑ\82еÑ\80е као бÑ\80зÑ\83 везÑ\83",
+ "rcfilters-savedqueries-add-new-title": "СаÑ\87Ñ\83ваÑ\98 Ñ\82Ñ\80енÑ\83Ñ\82не поÑ\81Ñ\82авке Ñ\84илÑ\82еÑ\80а",
"rcfilters-restore-default-filters": "Враћање подразумеваних филтера",
"rcfilters-clear-all-filters": "Уклони све филтере",
"rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
"lonelypagestext": "Следеће странице нису повезане с другим страницама, нити су укључене трансклузијом у друге странице.",
"uncategorizedpages": "Некатегорисане странице",
"uncategorizedcategories": "Некатегорисане категорије",
- "uncategorizedimages": "Ð\94аÑ\82оÑ\82еке без каÑ\82егоÑ\80иÑ\98а",
+ "uncategorizedimages": "Ð\9dекаÑ\82егоÑ\80иÑ\81ане даÑ\82оÑ\82еке",
"uncategorizedtemplates": "Некатегорисани шаблони",
"unusedcategories": "Некоришћене категорије",
"unusedimages": "Некоришћене датотеке",
"lonelypagestext": "Sledeće stranice nisu povezane s drugim stranicama, niti su uključene transkluzijom u druge stranice.",
"uncategorizedpages": "Nekategorisane stranice",
"uncategorizedcategories": "Nekategorisane kategorije",
- "uncategorizedimages": "Datoteke bez kategorija",
+ "uncategorizedimages": "Nekategorisane datoteke",
"uncategorizedtemplates": "Nekategorisani šabloni",
"unusedcategories": "Nekorišćene kategorije",
"unusedimages": "Nekorišćene datoteke",
"sat": "Шн",
"january": "Январ",
"february": "Феврал",
- "march": "Ð\9cарт",
- "april": "Ð\90прел",
+ "march": "март",
+ "april": "апрел",
"may_long": "май",
"june": "Июн",
"july": "Июл",
"retypenew": "Калимаи нави убурро такроран нависед:",
"resetpass_submit": "Калимаи убурро танзим карда ба систем вуруд кунед",
"changepassword-success": "Гузарвожаи шумо бо муваффақият тағйир дода шуд!",
+ "botpasswords-label-cancel": "Пӯшидан",
"resetpass_forbidden": "Гузарвожаҳоро наметавон тағйир дод",
"resetpass-no-info": "Барои дастрасии мустақим ба ин саҳифа шумо бояд ба систем ворид шуда бошед.",
"resetpass-submit-loggedin": "Тағйири гузарвожа",
"session_fail_preview_html": "'''Бубахшед! Имкони сабти вироиши шумо ба хотир аз даст рафтани иттилоот нишаст.'''\n\n''Бо таваҷҷӯҳ ба ин ки дар {{SITENAME}} имкони HTML хом фаъол аст, пешнамоиши саҳифа пинҳон шуда то имкони зидди ҳамалоти ҶаваСкрипт вуҷуд ндошта бошад.''\n\n'''Агар боварӣ доред, ки ин пешнамоиш як вироиши миҷоз ас, онро такрор кунед. Агар пешнамоиш натиҷае надод, аз систем хориҷ шавед ва дубора ворид шавед'''",
"token_suffix_mismatch": "'''Вироишҳои шумо захира нашуд, зеро мурургари шумо навиштаҳои нуқтагузориро аз ҳам пошида аст. Вироиши шумо захира нашуд то аз вайрон шудани матни саҳифа пешгирӣ кунад.\nБаъзан ин хато вақте пайдо мешавад, ки шумо аз хизмати (web-based proxy) истифода мекунед.'''",
"edit_form_incomplete": "<strong>Бархе аз қисмати форми вироиш ба пойгоҳ нарасид; дубора бисанҷед, ки вироишоти шумо дуруст аст ва дубора саъй кунед.</strong>",
- "editing": "Дар ҳоли вироиш $1",
+ "editing": "Дар ҳоли вироиши $1",
"creating": "Дар ҳоли эҷоди $1",
"editingsection": "Дар ҳоли вироиши $1 (қисмат)",
"editingcomment": "Дар ҳоли вироиши $1 (қисми нав)",
"revdelete-hide-user": "Номи корбар/нишонаи IP",
"revdelete-hide-restricted": "Фурунишонии иттилоот барои мудирон ба ҳамроҳи дигарон",
"revdelete-radio-same": "(тағйир надиҳед)",
- "revdelete-radio-set": "Пинҳон",
+ "revdelete-radio-set": "Пинҳонкарда",
"revdelete-radio-unset": "Намоён",
"revdelete-suppress": "Аз дастрасии мудирон ба додаҳо низ монанди сайри корбарон ҷилавгирӣ ба амал ояд",
"revdelete-unsuppress": "Хотимаи маҳдудиятҳо дар мавриди нусхаҳои интихобшуда",
"notextmatches": "Матни ҳеҷ мақолае рост намеояд",
"prevn": "{{PLURAL:$1|$1-тои}} қаблӣ",
"nextn": "{{PLURAL:$1|$1-тои}} навбатӣ",
+ "next-page": "саҳифаи навбатӣ",
"prevn-title": "Қаблӣ $1 {{PLURAL:$1|натиҷа|натоиҷ}}",
"nextn-title": "Баъдӣ $1 {{PLURAL:$1|натиҷа|натоиҷ}}",
"shown-title": "Намоиши $1 {{PLURAL:$1|натиҷа|натоиҷ}} дар ҳар саҳифа",
"recentchanges-label-minor": "Ин вироиши ҷузъи аст",
"recentchanges-label-bot": "Ин вироишро робот анҷом додааст",
"recentchanges-label-unpatrolled": "Ин вироиш ҳанӯз гаштзанӣ нашудааст",
+ "rcfilters-savedqueries-cancel-label": "Лағв",
"rcnotefrom": "Дар зер тағйиротҳои охирин аз <b>$2</b> (то <b>$1</b> нишон дода шудааст).",
"rclistfrom": "Нишон додани тағйиротҳои нав сар карда аз $3 $2",
"rcshowhideminor": "$1 вироишҳои хурд",
- "rcshowhideminor-show": "Намоиш",
- "rcshowhideminor-hide": "Пинҳон",
+ "rcshowhideminor-show": "Намоиш додани",
+ "rcshowhideminor-hide": "Пинҳон кардани",
"rcshowhidebots": "$1 ботҳо",
"rcshowhidebots-show": "Намоиш",
- "rcshowhidebots-hide": "Пинҳон",
+ "rcshowhidebots-hide": "Пинҳон кардани",
"rcshowhideliu": "$1 корбарони сабтиномшуда",
"rcshowhideliu-show": "Намоиш",
- "rcshowhideliu-hide": "Пинҳон",
+ "rcshowhideliu-hide": "Пинҳон кардани",
"rcshowhideanons": "$1 корбарони вуруднашуда",
"rcshowhideanons-show": "Намоиш",
- "rcshowhideanons-hide": "Пинҳон",
+ "rcshowhideanons-hide": "Пинҳон кардани",
"rcshowhidepatr": "$1 вироишҳои гаштӣ",
"rcshowhidepatr-show": "Намоиш",
- "rcshowhidepatr-hide": "Пинҳон",
+ "rcshowhidepatr-hide": "Пинҳон кардани",
"rcshowhidemine": "$1 вироишҳои ман",
"rcshowhidemine-show": "Намоиш",
- "rcshowhidemine-hide": "Пинҳон",
+ "rcshowhidemine-hide": "Пинҳон кардани",
"rclinks": "Нишон додани $1 тағйироти охирин дар $2 рӯзи охир",
"diff": "фарқият",
"hist": "таърих",
"statistics-header-hooks": "Дигар омор",
"statistics-articles": "Саҳифаҳои мӯҳтаво",
"statistics-pages": "Саҳифаҳо",
+ "statistics-pages-desc": "Тамоми саҳифаҳо дар ин вики-сомона (саҳифаҳои равонакунӣ, баҳсҳо ва ғ.)",
"statistics-files": "Парвандаҳои боршуда",
+ "statistics-edits": "Шумораи вироишҳо аз замони эҷоди ин {{SITENAME}}",
"statistics-users": "[[Special:ListUsers|Корбарони]] сабтиномшуда",
"statistics-users-active": "Корбарони фаъол",
"pageswithprop-submit": "Бирав",
"withoutinterwiki": "Саҳифаҳои бидуни пайвандҳои забонӣ",
"withoutinterwiki-summary": "Саҳифаҳои зерин пайванде ба забони дигар надоранд:",
"withoutinterwiki-legend": "Пешванд",
- "withoutinterwiki-submit": "Намоиш",
+ "withoutinterwiki-submit": "Намоиши",
"fewestrevisions": "Саҳифаҳое, ки шумораи ками нусхаҳо доранд",
"nbytes": "$1 {{PLURAL:$1|байт|байт}}",
"ncategories": "$1 {{PLURAL:$1|гурӯҳ|гурӯҳҳо}}",
"logempty": "Мавриди мутобиқ ба манзури шумо дар гузориш пайдо нашуд.",
"log-title-wildcard": "Саҳифаҳоеро ҷустуҷӯ кунед, ки унвонашон бо ин матн оғоз мешаванд",
"allpages": "Ҳамаи саҳифаҳо",
- "nextpage": "СаҳиÑ\84аи баÑ\8aдина ($1)",
+ "nextpage": "СаҳиÑ\84аи навбаÑ\82Ó£ ($1)",
"prevpage": "Саҳифаи пешина ($1)",
"allpagesfrom": "Намоиши саҳифаҳо бо шурӯъ аз:",
"allpagesto": "Намоиши саҳифаҳо бо поёни дар:",
"mailnologin": "Нишонае аз фиристанда вуҷуд надорад",
"mailnologintext": "Барои фиристодани почтаи электронӣ барои корбарони дигар бояд [[Special:UserLogin|ба систем ворид шавед]] ва нишонаи почтаи электронии мӯътабар дар [[Special:Preferences|тарҷиҳоти]] худ дошта бошед.",
"emailuser": "Фиристодани email ба ин корбар",
+ "emailuser-title-target": "Навиштани мактуб ба email-и ин корбар",
"emailuser-title-notarget": "Фиристодани пайём ба корбар",
"emailpagetext": "Агар ин корбар нишонаи почтаи электронии мӯътабаре дар тарҷиҳоти ворид карда бошад, форми зерин як пайғоме мефиристад.\nНишонаи почтаи электроние, ки шумо дар тарҷиҳоти корбариатон ворид кардаед, дар нишони фиристандаи нома \"From\" хоҳад омад, то ки гиранда тавонад ба шумо посух диҳад.",
"defemailsubject": "Пайёми {{SITENAME}} аз корбар \"$1\"",
"unblocked": "Дастрасии [[User:$1|$1]] боз карда шуд",
"unblocked-id": "Қатъи дастрасии шумораи $1 хотима ёфт",
"blocklist": "Корбарони басташуда",
+ "autoblocklist-submit": "Ҷустуҷӯ",
"ipblocklist": "Корбарони басташуда",
"ipblocklist-legend": "Ҷустуҷӯи корбари баста шуда",
"blocklist-target": "Ҳадаф",
"tooltip-pt-preferences": "Тарҷиҳоти ман",
"tooltip-pt-watchlist": "Рӯйхати саҳифаҳое, ки тағйиротҳояшонро Шумо назорат мекунед",
"tooltip-pt-mycontris": "Феҳристи ҳиссагузориҳои шумо",
- "tooltip-pt-login": "Тавсия мешавад ки ба систем ворид шавад, лекин иҷборӣ нест.",
+ "tooltip-pt-login": "Тавсия мешавад ки ба система ворид шавед, лекин маҷбурӣ нест.",
"tooltip-pt-logout": "Хуруҷ аз систем",
"tooltip-ca-talk": "Баҳси матни таркибии ин саҳифа",
"tooltip-ca-edit": "Шумо ин саҳифаро вироиш карда метавонед. Пеш аз захира кардани саҳифа пешнамоишро истифода баред.",
"exif-gpsdatestamp": "Таърихи ҶПС",
"exif-gpsdifferential": "Тасҳеҳи ҷузъии ҶПС",
"exif-keywords": "Калидвожаҳо",
+ "exif-languagecode": "Забон",
"exif-compression-1": "Ғайрифишурда",
"exif-unknowndate": "Таърихи номаълум",
"exif-orientation-1": "Оддӣ",
"recreate": "Аз нав созед",
"confirm_purge_button": "Таъйид",
"confirm-purge-top": "Пок карадни нусхаи ҳофизаи ниҳонии (Cache) ин саҳифаро таъйид мекунед?",
- "imgmultipageprev": "← саҳифаи пешин",
- "imgmultipagenext": "саҳифаи баъд →",
+ "imgmultipageprev": "← саҳифаи пешина",
+ "imgmultipagenext": "саҳифаи баъдӣ →",
"imgmultigo": "Бирав!",
"imgmultigoto": "Ба саҳифаи $1 равед",
"ascending_abbrev": "афзуншаванда",
"expand_templates_remove_comments": "Ҳазфи тавзеҳот",
"expand_templates_generate_xml": "Намоиши дарахти таҷзеҳи XML",
"expand_templates_preview": "Пешнамоиш",
+ "special-characters-group-cyrillic": "Сириллик",
"randomrootpage": "Саҳифаи решавии тасодуфӣ",
"changecredentials-submit": "Тағйири ҳисоби корбарӣ",
"removecredentials-submit": "Хориҷи эътиборнома"
"recentchanges-legend-heading": "<strong>Аңлатма:</strong>",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шулай ук [[Special:NewPages|яңа битләр исемлеген]] карагыз)",
"recentchanges-submit": "Күрсәт",
- "rcfilters-quickfilters": "Сакланган филтр көйләнмәләре",
+ "rcfilters-activefilters": "Актив фильтрлар",
+ "rcfilters-quickfilters": "Сакланган фильтрлар",
"rcfilters-clear-all-filters": "Барлык филтерләрне чистарту",
+ "rcfilters-search-placeholder": "Фильтрланы соңгы үзгәртү (карау яисә кертүне башлау)",
"rcfilters-filter-registered-label": "Теркәлгән",
"rcfilters-filter-registered-description": "Теркәлгән мөхәррирләр.",
"rcfilters-filter-user-experience-level-experienced-label": "Тәҗрибәле кулланучылар",
"confirmrecreate": "在您編輯的同時,使用者 [[User:$1|$1]] ([[User talk:$1|對話]]) 刪除了此頁面,原因為:\n: <em>$2</em>\n請確認您是否真的要重新建立此頁面。",
"confirmrecreate-noreason": "在您編輯的同時,使用者 [[User:$1|$1]] ([[User talk:$1|對話]]) 刪除了此頁面,請確認您是否真的要重新建立此頁面。",
"recreate": "重新建立",
- "confirm-purge-title": "刷新本頁",
+ "confirm-purge-title": "清除此頁快取",
"confirm_purge_button": "確定",
"confirm-purge-top": "要清除此頁面的快取嗎?",
"confirm-purge-bottom": "刷新頁面會清空頁面的快取記錄並強制顯示最近的頁面修訂。",
parent::__construct();
$this->addDescription( 'Deletes all pages in the MediaWiki namespace' .
' which were last edited by "MediaWiki default"' );
+ $this->addOption( 'dry-run', 'Perform a dry run, delete nothing' );
}
public function execute() {
);
if ( $dbr->numRows( $res ) == 0 ) {
- # No more messages left
+ // No more messages left
$this->output( "done.\n" );
+ return;
+ }
+ $dryrun = $this->hasOption( 'dry-run' );
+ if ( $dryrun ) {
+ foreach ( $res as $row ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $this->output( "\n* [[$title]]" );
+ }
+ $this->output( "\n\nRun again without --dry-run to delete these pages.\n" );
return;
}
- # Deletions will be made by $user temporarly added to the bot group
- # in order to hide it in RecentChanges.
+ // Deletions will be made by $user temporarly added to the bot group
+ // in order to hide it in RecentChanges.
$user = User::newFromName( 'MediaWiki default' );
if ( !$user ) {
$this->error( "Invalid username", true );
$user->addGroup( 'bot' );
$wgUser = $user;
- # Handle deletion
+ // Handle deletion
$this->output( "\n...deleting old default messages (this may take a long time!)...", 'msg' );
$dbw = $this->getDB( DB_MASTER );
function syncText() {
var value = $( this ).val()
- .replace( /[\[\]\{\}|#<>%+? ]/g, '_' )
+ .replace( /[\[\]{}|#<>%+? ]/g, '_' ) // eslint-disable-line no-useless-escape
.replace( /&/, '&' )
.replace( /__+/g, '_' )
.replace( /^_+/, '' )
}
// Set up the help system
- $( '.config-help-field-data' )
- .hide()
- .closest( '.config-help-field-container' )
- .find( '.config-help-field-hint' )
- .show()
- .click( function () {
- $( this )
- .closest( '.config-help-field-container' )
- .find( '.config-help-field-data' )
- .slideToggle( 'fast' );
- } );
+ $( '.config-help-field-data' ).hide()
+ .closest( '.config-help-field-container' ).find( '.config-help-field-hint' )
+ .show()
+ .click( function () {
+ $( this ).closest( '.config-help-field-container' ).find( '.config-help-field-data' )
+ .slideToggle( 'fast' );
+ } );
// Show/hide code for DB-specific options
// FIXME: Do we want slow, fast, or even non-animated (instantaneous) showing/hiding here?
"grunt-banana-checker": "0.6.0",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-watch": "1.0.0",
- "grunt-eslint": "19.0.0",
+ "grunt-eslint": "20.0.0",
"grunt-jsonlint": "1.1.0",
"grunt-karma": "2.0.0",
- "grunt-stylelint": "0.7.0",
+ "grunt-stylelint": "0.8.0",
"grunt-webdriver": "2.0.3",
"karma": "1.5.0",
"karma-chrome-launcher": "2.0.0",
"karma-qunit": "1.0.0",
"nodemw": "0.10.1",
"qunitjs": "1.23.1",
+ "stylelint": "7.8.0",
"stylelint-config-wikimedia": "0.4.1",
"wdio-junit-reporter": "0.2.0",
"wdio-mocha-framework": "0.5.8",
'rcfilters-tag-prefix-namespace',
'rcfilters-tag-prefix-namespace-inverted',
'rcfilters-tag-prefix-tags',
+ 'rcfilters-exclude-button-off',
+ 'rcfilters-exclude-button-on',
'rcfilters-view-tags',
'rcfilters-view-namespaces-tooltip',
'rcfilters-view-tags-tooltip',
if ( $badge.length ) {
$badge
.toggleClass( 'mw-badge-important', isImportant )
- .find( '.mw-badge-content' )
- .text( text );
+ .find( '.mw-badge-content' ).text( text );
} else {
// Otherwise, create a new badge with the specified text and style
$badge = $( '<div class="mw-badge"></div>' )
// Look for rgb(num%,num%,num%)
// eslint-disable-next-line no-cond-assign
- if ( result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec( color ) ) {
+ if ( result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec( color ) ) {
return [
parseFloat( result[ 1 ] ) * 2.55,
parseFloat( result[ 2 ] ) * 2.55,
buildDefaultToggleLink = function () {
return $( '<a class="mw-collapsible-text"></a>' )
.text( collapseText )
- .wrap( '<span class="mw-collapsible-toggle"></span>' ).parent()
- .attr( {
- role: 'button',
- tabindex: 0
- } )
- .prepend( '<span>[</span>' )
- .append( '<span>]</span>' )
- .on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
+ .wrap( '<span class="mw-collapsible-toggle"></span>' )
+ .parent()
+ .attr( {
+ role: 'button',
+ tabindex: 0
+ } )
+ .prepend( '<span>[</span>' )
+ .append( '<span>]</span>' )
+ .on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
};
// Check if this element has a custom position for the toggle link
},
trimRight: function ( str ) {
return str === null ?
- '' : str.toString().replace( /\s+$/, '' );
+ '' : str.toString().replace( /\s+$/, '' );
},
ucFirst: function ( str ) {
return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
} );
mw.log.deprecate( $, 'escapeRE', function ( str ) {
- return str.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
+ return str.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ); // eslint-disable-line no-useless-escape
}, 'Use mediawiki.RegExp instead.' );
}( jQuery, mediaWiki ) );
* @class jQuery.plugin.suggestions
*/
- // jscs:disable checkParamNames
/**
* @method suggestions
* @chainable
* @param {boolean} [options.highlightInput=false] Whether to highlight matched portions of the
* input or not.
*/
- // jscs:enable checkParamNames
( function ( $, mw ) {
27, // escape
13, // enter
46, // delete
- 8 // backspace
+ 8 // backspace
];
if ( context.data.keypressedCount === 0 &&
e.which === context.data.keypressed &&
// Build RegEx
// Any date formated with . , ' - or /
- ts.dateRegex[ 0 ] = new RegExp( /^\s*(\d{1,2})[\,\.\-\/'\s]{1,2}(\d{1,2})[\,\.\-\/'\s]{1,2}(\d{2,4})\s*?/i );
+ ts.dateRegex[ 0 ] = new RegExp( /^\s*(\d{1,2})[,.\-/'\s]{1,2}(\d{1,2})[,.\-/'\s]{1,2}(\d{2,4})\s*?/i );
// Written Month name, dmy
ts.dateRegex[ 1 ] = new RegExp(
}
columnToCell = [];
- cellsInRow = ( $row[ 0 ].cells.length ) || 0; // all cells in this row
+ cellsInRow = ( $row[ 0 ].cells.length ) || 0; // all cells in this row
index = 0; // real cell index in this row
for ( j = 0; j < columns; index++ ) {
if ( index === cellsInRow ) {
}
ts.rgx = {
IPAddress: [
- new RegExp( /^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/ )
+ new RegExp( /^\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}$/ )
],
currency: [
new RegExp( /(^[£$€¥]|[£$€¥]$)/ ),
new RegExp( /(https?|ftp|file):\/\// )
],
isoDate: [
- new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)([T\s]((([01]\d|2[0-3])(:?[0-5]\d)?|24:?00)?(:?([0-5]\d|60))?([.,]\d+)?)([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?/ ),
+ new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)([T\s]((([01]\d|2[0-3])(:?[0-5]\d)?|24:?00)?(:?([0-5]\d|60))?([.,]\d+)?)([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?/ ),
new RegExp( /^([-+]?\d{1,4})-([01]\d)-([0-3]\d)/ )
],
usLongDate: [
return getParserById( id );
},
- getParsers: function () { // for table diagnosis
+ getParsers: function () { // for table diagnosis
return parsers;
}
};
role: 'navigation',
'aria-labelledby': 'p-lang-label'
} )
- .append( $( '<h3>' ).attr( 'id', 'p-lang-label' ).text( mw.msg( 'otherlanguages' ) ) )
- .append( $( '<div>' ).addClass( 'body' ).append( '<ul>' ) )
+ .append( $( '<h3>' ).attr( 'id', 'p-lang-label' ).text( mw.msg( 'otherlanguages' ) ) )
+ .append( $( '<div>' ).addClass( 'body' ).append( '<ul>' ) )
);
}
return true;
}
- $lis
- .each( function () {
+ $lis.each( function () {
$li = $( this );
$inputs = $li.find( 'input[type="radio"]' );
$oldidRadio = $inputs.filter( '[name="oldid"]' ).eq( 0 );
// Also remove potentially conflicting id attributes that we don't need anyway
$copyForm
.css( 'display', 'none' )
- .find( '[id]' )
- .removeAttr( 'id' )
+ .find( '[id]' ).removeAttr( 'id' )
.end()
.insertAfter( $historyCompareForm )
.submit();
$col = $( '<td colspan="2"></td>' );
$link = $( '<a>' )
- .text( showText )
- .attr( {
- role: 'button',
- tabindex: 0
- } )
- .on( 'click keypress', function ( e ) {
- if (
- e.type === 'click' ||
- e.type === 'keypress' && e.which === 13
- ) {
- if ( $table.hasClass( 'collapsed' ) ) {
- $( this ).text( hideText );
- } else {
- $( this ).text( showText );
+ .text( showText )
+ .attr( {
+ role: 'button',
+ tabindex: 0
+ } )
+ .on( 'click keypress', function ( e ) {
+ if (
+ e.type === 'click' ||
+ e.type === 'keypress' && e.which === 13
+ ) {
+ if ( $table.hasClass( 'collapsed' ) ) {
+ $( this ).text( hideText );
+ } else {
+ $( this ).text( showText );
+ }
+ $table.toggleClass( 'expanded collapsed' );
}
- $table.toggleClass( 'expanded collapsed' );
- }
- } );
+ } );
$col.append( $link );
$row.append( $col );
// Go over the items and define the correct values
$.each( filterRepresentation, function ( name, value ) {
+ // We must store all parameter values as strings '0' or '1'
result[ filterParamNames[ name ] ] = areAnySelected ?
- // We must store all parameter values as strings '0' or '1'
String( Number( !value ) ) :
'0';
} );
$.each( paramRepresentation, function ( paramName, paramValue ) {
var filterItem = paramToFilterMap[ paramName ];
+ // Flip the definition between the parameter
+ // state and the filter state
+ // This is what the 'toggleSelected' value of the filter is
result[ filterItem.getName() ] = areAnySelected ?
- // Flip the definition between the parameter
- // state and the filter state
- // This is what the 'toggleSelected' value of the filter is
!Number( paramValue ) :
// Otherwise, there are no selected items in the
// group, which means the state is false
);
// Translate the parameter values into a filter selection state
this.getItems().forEach( function ( filterItem ) {
+ // All true (either because all values are written or the term 'all' is written)
+ // is the same as all filters set to true
result[ filterItem.getName() ] = (
- // If it is the word 'all'
- paramValues.length === 1 && paramValues[ 0 ] === 'all' ||
- // All values are written
- paramValues.length === model.getItemCount()
- ) ?
- // All true (either because all values are written or the term 'all' is written)
- // is the same as all filters set to true
+ // If it is the word 'all'
+ paramValues.length === 1 && paramValues[ 0 ] === 'all' ||
+ // All values are written
+ paramValues.length === model.getItemCount()
+ ) ?
true :
// Otherwise, the filter is selected only if it appears in the parameter values
paramValues.indexOf( filterItem.getParamName() ) > -1;
} );
};
+ /**
+ * Get all selected items
+ *
+ * @return {mw.rcfilters.dm.FilterItem[]} Selected items
+ */
+ mw.rcfilters.dm.FiltersViewModel.prototype.getSelectedItems = function () {
+ var allSelected = [];
+
+ $.each( this.getFilterGroups(), function ( groupName, groupModel ) {
+ allSelected = allSelected.concat( groupModel.getSelectedItems() );
+ } );
+
+ return allSelected;
+ };
/**
* Switch the current view
*
this.baseFilterState = {};
this.uriProcessor = null;
this.initializing = false;
+
+ this.prevLoggedItems = [];
};
/* Initialization */
this.filtersModel.toggleFilterSelected( filterName, false );
this.updateChangesList();
this.filtersModel.reassessFilterInteractions( filterItem );
+
+ // Log filter grouping
+ this.trackFilterGroupings( 'removefilter' );
}
if ( isHighlighted ) {
this.filtersModel.reassessFilterInteractions();
this.updateChangesList();
+
+ // Log filter grouping
+ this.trackFilterGroupings( 'savedfilters' );
}
};
);
};
+ /**
+ * Track filter grouping usage
+ *
+ * @param {string} action Action taken
+ */
+ mw.rcfilters.Controller.prototype.trackFilterGroupings = function ( action ) {
+ var controller = this,
+ rightNow = new Date().getTime(),
+ randomIdentifier = String( mw.user.sessionId() ) + String( rightNow ) + String( Math.random() ),
+ // Get all current filters
+ filters = this.filtersModel.getSelectedItems().map( function ( item ) {
+ return item.getName();
+ } );
+
+ action = action || 'filtermenu';
+
+ // Check if these filters were the ones we just logged previously
+ // (Don't log the same grouping twice, in case the user opens/closes)
+ // the menu without action, or with the same result
+ if (
+ // Only log if the two arrays are different in size
+ filters.length !== this.prevLoggedItems.length ||
+ // Or if any filters are not the same as the cached filters
+ filters.some( function ( filterName ) {
+ return controller.prevLoggedItems.indexOf( filterName ) === -1;
+ } ) ||
+ // Or if any cached filters are not the same as given filters
+ this.prevLoggedItems.some( function ( filterName ) {
+ return filters.indexOf( filterName ) === -1;
+ } )
+ ) {
+ filters.forEach( function ( filterName ) {
+ mw.track(
+ 'event.ChangesListFilterGrouping',
+ {
+ action: action,
+ groupIdentifier: randomIdentifier,
+ filter: filterName,
+ userId: mw.user.getId()
+ }
+ );
+ } );
+
+ // Cache the filter names
+ this.prevLoggedItems = filters;
+ }
+ };
}( mediaWiki, jQuery ) );
.mw-rcfilters-ui-savedLinksListItemWidget {
- padding: 0.2em 0.7em;
+ padding: 0 0.5em;
+ line-height: normal;
&:hover {
// Mimicking optionWidget styles
&-content {
width: 100%;
+ line-height: normal;
}
}
// Invert namespaces button
this.invertNamespacesButton = new OO.ui.ToggleButtonWidget( {
icon: '',
- label: mw.msg( 'invert' ),
classes: [ 'mw-rcfilters-ui-filterMenuHeaderWidget-invertNamespacesButton' ]
} );
this.invertNamespacesButton.toggle( this.model.getCurrentView() === 'namespaces' );
+ this.updateInvertButton( this.model.areNamespacesInverted() );
// Events
this.backButton.connect( this, { click: 'onBackButtonClick' } );
* @param {boolean} isInverted Namespaces selection is inverted
*/
mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.onModelInvertChange = function ( isInverted ) {
+ this.updateInvertButton( isInverted );
+ };
+
+ /**
+ * Update the state of the invert button
+ *
+ * @param {boolean} isInverted Namespaces selection is inverted
+ */
+ mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.updateInvertButton = function ( isInverted ) {
this.invertNamespacesButton.setActive( isInverted );
+ this.invertNamespacesButton.setLabel(
+ isInverted ?
+ mw.msg( 'rcfilters-exclude-button-on' ) :
+ mw.msg( 'rcfilters-exclude-button-off' )
+ );
};
mw.rcfilters.ui.FilterMenuHeaderWidget.prototype.onBackButtonClick = function () {
classes: [ 'mw-rcfilters-ui-filterMenuSectionOptionWidget-whatsThisButton' ],
flags: [ 'progressive' ],
popup: {
- $autoCloseIgnore: this.$element.add( this.$overlay ),
padded: false,
align: 'center',
position: 'above',
// Clear the input
this.input.setValue( '' );
}
+
+ // Log filter grouping
+ this.controller.trackFilterGroupings( 'filtermenu' );
}
this.input.setIcon( isVisible ? 'search' : 'menu' );
this.inputValue = '';
this.$overlay = config.$overlay || this.$element;
- this.$body = $( '<div>' )
- .addClass( 'mw-rcfilters-ui-menuSelectWidget-body' );
+ this.$body = $( '<div>' ).addClass( 'mw-rcfilters-ui-menuSelectWidget-body' );
this.footers = [];
// Parent
-/* jshint -W024*/
( function ( mw, $ ) {
$( function () {
- mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' );
- mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
+ var startInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' ),
+ endInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
+
+ startInput.on( 'deactivate', function ( userSelected ) {
+ if ( userSelected ) {
+ endInput.focus();
+ }
+ } );
} );
}( mediaWiki, jQuery ) );
'aria-labelledby': labelFunc
} );
$fieldsets.not( '#mw-prefsection-personal' )
- .hide()
- .attr( 'aria-hidden', 'true' );
+ .hide()
+ .attr( 'aria-hidden', 'true' );
// T115692: The following is kept for backwards compatibility with older skins
$preferences.addClass( 'jsprefs' );
$tab.attr( {
tabIndex: 0,
'aria-selected': 'true'
- } )
- .focus()
+ } ).focus()
.parent().addClass( 'selected' );
$preferences.children( 'fieldset' ).hide().attr( 'aria-hidden', 'true' );
function detectHash() {
var hash = location.hash,
matchedElement, parentSection;
- if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
+ if ( hash.match( /^#mw-prefsection-[\w-]+/ ) ) {
mw.storage.session.remove( 'mwpreferences-prevTab' );
switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
- } else if ( hash.match( /^#mw-[\w\-]+/ ) ) {
+ } else if ( hash.match( /^#mw-[\w-]+/ ) ) {
matchedElement = document.getElementById( hash.slice( 1 ) );
parentSection = $( matchedElement ).closest( '.prefsection' );
if ( parentSection.length ) {
) {
$( window ).on( 'hashchange', function () {
var hash = location.hash;
- if ( hash.match( /^#mw-[\w\-]+/ ) ) {
+ if ( hash.match( /^#mw-[\w-]+/ ) ) {
detectHash();
} else if ( hash === '' ) {
switchPrefTab( 'personal', 'noHash' );
}
} )
- // Run the function immediately to select the proper tab on startup.
- .trigger( 'hashchange' );
+ // Run the function immediately to select the proper tab on startup.
+ .trigger( 'hashchange' );
// In older browsers we'll bind a click handler as fallback.
// We must not have onhashchange *and* the click handlers, otherwise
// the click handler calls switchPrefTab() which sets the hash value,
piprop: 'thumbnail',
pithumbsize: 300,
formatversion: 2
- } )
- .done( function ( resp ) {
+ } ).done( function ( resp ) {
var results = ( resp.query && resp.query.pages ) ? resp.query.pages : false,
multimediaWidgetTemplate;
if ( v.normalize ) {
v = v.normalize();
}
- re = new RegExp( '^\\s*' + v.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' ), 'i' );
+ re = new RegExp( '^\\s*' + v.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ), 'i' ); // eslint-disable-line no-useless-escape
for ( k in this.values ) {
k = +k;
if ( !isNaN( k ) && re.test( this.values[ k ] ) ) {
/* Methods */
+ /**
+ * Get the currently focused field, if any
+ *
+ * @private
+ * @return {jQuery}
+ */
+ mw.widgets.datetime.DateTimeInputWidget.prototype.getFocusedField = function () {
+ return this.$fields.find( this.getElementDocument().activeElement );
+ };
+
/**
* Convert a date string to a Date
*
var delta = 0,
spec = $field.data( 'mw-widgets-datetime-dateTimeInputWidget-fieldSpec' );
- if ( this.isDisabled() ) {
+ if ( this.isDisabled() || !this.getFocusedField().length ) {
return;
}
* @inheritdoc
*/
mw.widgets.datetime.DateTimeInputWidget.prototype.focus = function () {
- if ( !this.$fields.find( document.activeElement ).length ) {
+ if ( !this.getFocusedField().length ) {
this.$fields.find( '.mw-widgets-datetime-dateTimeInputWidget-editField' ).first().focus();
}
return this;
* @inheritdoc
*/
mw.widgets.datetime.DateTimeInputWidget.prototype.blur = function () {
- this.$fields.find( document.activeElement ).blur();
+ this.getFocusedField().blur();
return this;
};
var queryValue = this.query.getValue().trim();
if ( queryValue.match( this.externalLinkUrlProtocolsRegExp ) ) {
- queryValue = queryValue.match( /.+\/([^\/]+)/ )[ 1 ];
+ queryValue = queryValue.match( /.+\/([^/]+)/ )[ 1 ];
}
return queryValue;
};
);
currentMonth.add( 1, 'month' );
}
- // Shuffle the array to display months in columns rather than rows.
+ // Shuffle the array to display months in columns rather than rows:
+ // | Jan | Jul |
+ // | Feb | Aug |
+ // | Mar | Sep |
+ // | Apr | Oct |
+ // | May | Nov |
+ // | Jun | Dec |
items = [
- items[ 0 ], items[ 6 ], // | January | July |
- items[ 1 ], items[ 7 ], // | February | August |
- items[ 2 ], items[ 8 ], // | March | September |
- items[ 3 ], items[ 9 ], // | April | October |
- items[ 4 ], items[ 10 ], // | May | November |
- items[ 5 ], items[ 11 ] // | June | December |
+ items[ 0 ], items[ 6 ],
+ items[ 1 ], items[ 7 ],
+ items[ 2 ], items[ 8 ],
+ items[ 3 ], items[ 9 ],
+ items[ 4 ], items[ 10 ],
+ items[ 5 ], items[ 11 ]
];
break;
} );
this.inCalendar = 0;
this.inTextInput = 0;
+ this.closing = false;
this.inputFormat = config.inputFormat;
this.displayFormat = config.displayFormat;
this.longDisplayFormat = config.longDisplayFormat;
this.$handle.on( {
click: this.onClick.bind( this ),
keypress: this.onKeyPress.bind( this ),
- focus: this.activate.bind( this )
+ focus: this.onFocus.bind( this )
} );
// Initialization
OO.inheritClass( mw.widgets.DateInputWidget, OO.ui.TextInputWidget );
OO.mixinClass( mw.widgets.DateInputWidget, OO.ui.mixin.IndicatorElement );
+ /* Events */
+
+ /**
+ * Fired when the widget is deactivated (i.e. the calendar is closed). This can happen because
+ * the user selected a value, or because the user blurred the widget.
+ *
+ * @event deactivate
+ * @param {boolean} userSelected Whether the deactivation happened because the user selected a value
+ */
+
/* Methods */
/**
* Deactivate this input field for data entry. Closes the calendar and hides the text field.
*
* @private
+ * @param {boolean} [userSelected] Whether we are deactivating because the user selected a value
*/
- mw.widgets.DateInputWidget.prototype.deactivate = function () {
+ mw.widgets.DateInputWidget.prototype.deactivate = function ( userSelected ) {
this.$element.removeClass( 'mw-widget-dateInputWidget-active' );
this.$handle.show();
this.textInput.toggle( false );
this.calendar.toggle( false );
this.setValidityFlag();
+
+ if ( userSelected ) {
+ // Prevent focusing the handle from reopening the calendar
+ this.closing = true;
+ this.$handle.focus();
+ this.closing = false;
+ }
+
+ this.emit( 'deactivate', !!userSelected );
};
/**
}
};
+ /**
+ * Handle focus events.
+ *
+ * @private
+ */
+ mw.widgets.DateInputWidget.prototype.onFocus = function () {
+ if ( !this.closing ) {
+ this.activate();
+ }
+ };
+
/**
* Handle calendar key press events.
*
*/
mw.widgets.DateInputWidget.prototype.onCalendarKeyPress = function ( e ) {
if ( !this.isDisabled() && e.which === OO.ui.Keys.ENTER ) {
- this.deactivate();
- this.$handle.focus();
+ this.deactivate( true );
return false;
}
};
if (
!this.isDisabled() &&
e.which === 1 &&
- $( e.target ).hasClass( 'mw-widget-calendarWidget-day' )
+ (
+ $( e.target ).hasClass( 'mw-widget-calendarWidget-day' ) ||
+ $( e.target ).hasClass( 'mw-widget-calendarWidget-month' )
+ )
) {
- this.deactivate();
- this.$handle.focus();
+ this.deactivate( true );
return false;
}
};
* @private
*/
mw.widgets.DateInputWidget.prototype.onEnter = function () {
- this.deactivate();
- this.$handle.focus();
+ this.deactivate( true );
};
/**
title: String( page ),
user: user,
uselang: mw.config.get( 'wgUserLanguage' )
- }, params ) )
- .then( function ( data ) {
+ }, params ) ).then( function ( data ) {
return data.rollback;
} );
}
upload = this.uploadWithFormData( file, data );
return upload.then(
- null,
- // If the call fails, we may want to try again...
- retries === 0 ? null : retry,
- function ( fraction ) {
- // Since we're only uploading small parts of a file, we
- // need to adjust the reported progress to reflect where
- // we actually are in the combined upload
- return ( start + fraction * ( end - start ) ) / file.size;
- }
- ).promise( { abort: upload.abort } );
+ null,
+ // If the call fails, we may want to try again...
+ retries === 0 ? null : retry,
+ function ( fraction ) {
+ // Since we're only uploading small parts of a file, we
+ // need to adjust the reported progress to reflect where
+ // we actually are in the combined upload
+ return ( start + fraction * ( end - start ) ) / file.size;
+ }
+ ).promise( { abort: upload.abort } );
},
/**
*/
function hideIfGetField( $el, name ) {
var $found, $p, $widget,
- suffix = name.replace( /^([^\[]+)/, '[$1]' );
+ suffix = name.replace( /^([^[]+)/, '[$1]' );
function nameFilter() {
return this.name === name ||
*/
mw.ForeignStructuredUpload.BookletLayout.prototype.saveFile = function () {
var title = mw.Title.newFromText(
- this.getFilename(),
- mw.config.get( 'wgNamespaceIds' ).file
- );
+ this.getFilename(),
+ mw.config.get( 'wgNamespaceIds' ).file
+ );
return this.uploadPromise
.then( this.validateFilename.bind( this, title ) )
* @return {string} Escaped string
*/
escape: function ( str ) {
- return str.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
+ return str.replace( /([\\{}()|.?*+\-^$\[\]])/g, '\\$1' ); // eslint-disable-line no-useless-escape
}
};
}( mediaWiki ) );
},
// brackets, greater than
{
- pattern: /[\]\}>]/g,
+ pattern: /[}\]>]/g,
replace: ')',
generalRule: true
},
// brackets, lower than
{
- pattern: /[\[\{<]/g,
+ pattern: /[{[<]/g,
replace: '(',
generalRule: true
},
}
// Any remaining initial :s are illegal.
- title = title.replace( /^\:+/, '' );
+ title = title.replace( /^:+/, '' );
return Title.newFromText( title, namespace );
};
thumbPhpRegex = /thumb\.php/,
regexes = [
// Thumbnails
- /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s\/]+)\/[^\s\/]+-[^\s\/]*$/,
+ /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)\/[^\s/]+-[^\s/]*$/,
// Full size images
- /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s\/]+)$/,
+ /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s/]+)$/,
// Thumbnails in non-hashed upload directories
- /\/([^\s\/]+)\/[^\s\/]+-(?:\1|thumbnail)[^\s\/]*$/,
+ /\/([^\s/]+)\/[^\s/]+-(?:\1|thumbnail)[^\s/]*$/,
// Full-size images in non-hashed upload directories
- /\/([^\s\/]+)$/
+ /\/([^\s/]+)$/
],
recount = regexes.length;
return $( '<div>' ).prop( {
id: 'mw-debug-' + id,
className: 'mw-debug-bit'
- } )
- .appendTo( $bits );
+ } ).appendTo( $bits );
}
/**
id: 'mw-debug-' + id,
className: 'mw-debug-bit mw-debug-panelink'
} )
- .append( paneLabel( id, text ) )
- .appendTo( $bits );
+ .append( paneLabel( id, text ) )
+ .appendTo( $bits );
}
paneTriggerBitDiv( 'console', 'Console', this.data.log.length );
.append( $( '<th>SQL</th>' ) )
.append( $( '<th>Time</th>' ).css( 'width', '8em' ) )
.append( $( '<th>Call</th>' ).css( 'width', '18em' ) )
- .appendTo( $table );
+ .appendTo( $table );
for ( i = 0, length = this.data.queries.length; i < length; i += 1 ) {
query = this.data.queries[ i ];
.append( $( '<td>' ).text( query.sql ) )
.append( $( '<td class="stats">' ).text( ( query.time * 1000 ).toFixed( 4 ) + 'ms' ) )
.append( $( '<td>' ).text( query[ 'function' ] ) )
- .appendTo( $table );
+ .appendTo( $table );
}
return $table;
*/
mw.Feedback.Dialog.prototype.validateFeedbackForm = function () {
var isValid = (
- (
- !this.useragentMandatory ||
- this.useragentCheckbox.isSelected()
- ) &&
- this.feedbackSubjectInput.getValue()
- );
+ (
+ !this.useragentMandatory ||
+ this.useragentCheckbox.isSelected()
+ ) &&
+ this.feedbackSubjectInput.getValue()
+ );
this.actions.setAbilities( { submit: isValid } );
};
// recursive functions seem not to work in all browsers then. (Tested IE6-7, Opera, Safari, FF)
// This may be because, to save code, memoization was removed
+ /* eslint-disable no-useless-escape */
regularLiteral = makeRegexParser( /^[^{}\[\]$<\\]/ );
regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ );
regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ );
regularLiteralWithSquareBrackets = makeRegexParser( /^[^{}$\\]/ );
+ /* eslint-enable no-useless-escape */
backslash = makeStringParser( '\\' );
doubleQuote = makeStringParser( '"' );
templateName = transform(
// see $wgLegalTitleChars
// not allowing : due to the need to catch "PLURAL:$1"
- makeRegexParser( /^[ !"$&'()*,.\/0-9;=?@A-Z\^_`a-z~\x80-\xFF+\-]+/ ),
+ makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
function ( result ) { return result.toString(); }
);
function templateParam() {
$el.attr( {
role: 'button',
tabindex: 0
- } )
- .on( 'click keypress', function ( e ) {
+ } ).on( 'click keypress', function ( e ) {
if (
e.type === 'click' ||
e.type === 'keypress' && e.which === 13
// Replace the default message parser with jqueryMsg
oldParser = mw.Message.prototype.parser;
mw.Message.prototype.parser = function () {
- if ( this.format === 'plain' || !/\{\{|[\[<>&]/.test( this.map.get( this.key ) ) ) {
+ if ( this.format === 'plain' || !/\{\{|[<>[&]/.test( this.map.get( this.key ) ) ) {
// Fall back to mw.msg's simple parser
return oldParser.apply( this );
}
function setGlobalMapValue( map, key, value ) {
map.values[ key ] = value;
log.deprecate(
- window,
- key,
- value,
- // Deprecation notice for mw.config globals (T58550, T72470)
- map === mw.config && 'Use mw.config instead.'
+ window,
+ key,
+ value,
+ // Deprecation notice for mw.config globals (T58550, T72470)
+ map === mw.config && 'Use mw.config instead.'
);
}
if ( options.tag ) {
// Sanitize options.tag before it is used by any code. (Including Notification class methods)
- options.tag = options.tag.replace( /[ _\-]+/g, '-' ).replace( /[^\-a-z0-9]+/ig, '' );
+ options.tag = options.tag.replace( /[ _-]+/g, '-' ).replace( /[^-a-z0-9]+/ig, '' );
if ( options.tag ) {
$notification.addClass( 'mw-notification-tag-' + options.tag );
} else {
if ( options.type ) {
// Sanitize options.type
- options.type = options.type.replace( /[ _\-]+/g, '-' ).replace( /[^\-a-z0-9]+/ig, '' );
+ options.type = options.type.replace( /[ _-]+/g, '-' ).replace( /[^-a-z0-9]+/ig, '' );
$notification.addClass( 'mw-notification-type-' + options.type );
}
* by that time.
*/
mw.requestIdleCallback = window.requestIdleCallback ?
- // Bind because it throws TypeError if context is not window
- window.requestIdleCallback.bind( window ) :
+ window.requestIdleCallback.bind( window ) : // Bind because it throws TypeError if context is not window
mw.requestIdleCallbackInternal;
// Note: Polyfill was previously disabled due to
// https://bugs.chromium.org/p/chromium/issues/detail?id=647870
*/
function getInputLocation( context ) {
return context.config.$region
- .closest( 'form' )
- .find( '[data-search-loc]' )
- .data( 'search-loc' ) || 'header';
+ .closest( 'form' )
+ .find( '[data-search-loc]' )
+ .data( 'search-loc' ) || 'header';
}
/**
var $this = $( this );
$this
.data( 'suggestions-context' )
- .data.$container
- .css( 'fontSize', $this.css( 'fontSize' ) );
+ .data.$container.css( 'fontSize', $this.css( 'fontSize' ) );
} );
// Ensure that the thing is actually present!
$tocToggleLink
.wrap( '<span class="toctoggle"></span>' )
.parent()
- .prepend( ' [' )
- .append( '] ' )
+ .prepend( ' [' )
+ .append( '] ' )
);
if ( hideToc ) {
formatversion: 2,
action: 'patrol',
rcid: rcid
- } )
- .done( function ( data ) {
+ } ).done( function ( data ) {
var title;
// Remove all patrollinks from the page (including any spinners inside).
$patrolLinks.closest( '.patrollink' ).remove();
// This should never happen as errors should trigger fail
mw.notify( mw.msg( 'markedaspatrollederrornotify' ), { type: 'error' } );
}
- } )
- .fail( function ( error ) {
+ } ).fail( function ( error ) {
$spinner.remove();
// Restore the patrol link. This allows the user to try again
// (or open it in a new window, bypassing this ajax module).
$( e.delegateTarget ).remove();
}, function ( errorCode, data ) {
var message = data && data.error && data.error.messageHtml ?
- $.parseHTML( data.error.messageHtml ) :
- mw.msg( 'rollbackfailed' ),
+ $.parseHTML( data.error.messageHtml ) :
+ mw.msg( 'rollbackfailed' ),
type = errorCode === 'alreadyrolled' ? 'warn' : 'error';
mw.notify( message, {
* @param string $text1
* @param string $text2
* @param int $numContextLines
+ * @param int $movedParagraphDetectionCutoff
* @return string
*/
-function wikidiff2_do_diff( $text1, $text2, $numContextLines ) {
+function wikidiff2_do_diff( $text1, $text2, $numContextLines, $movedParagraphDetectionCutoff = 0 ) {
}
* The key is added to the array of globals that will be reset afterwards
* in the tearDown().
*
- * @example
- * <code>
+ * @par Example
+ * @code
* protected function setUp() {
* $this->setMwGlobals( 'wgRestrictStuff', true );
* }
* }
*
* function testQuux() {}
- * </code>
+ * @endcode
*
* @param array|string $pairs Key to the global variable, or an array
* of key/value pairs.
return $mock;
}
- /** helper to test SpecialRecentchanges::buildMainQueryConds() */
- private function assertConditions(
- $expected,
+ private function buildQuery(
$requestOptions = null,
- $message = '',
$user = null
) {
$context = new RequestContext;
'ChangesListSpecialPageTest::filterOutRcTimestampCondition'
);
+ return $queryConditions;
+ }
+
+ /** helper to test SpecialRecentchanges::buildQuery() */
+ private function assertConditions(
+ $expected,
+ $requestOptions = null,
+ $message = '',
+ $user = null
+ ) {
+ $queryConditions = $this->buildQuery( $requestOptions, $user );
+
$this->assertEquals(
self::normalizeCondition( $expected ),
self::normalizeCondition( $queryConditions ),
);
}
+ public function testFilterUserExpLevelAll() {
+ $this->assertConditions(
+ [
+ # expected
+ ],
+ [
+ 'userExpLevel' => 'registered;unregistered;newcomer;learner;experienced',
+ ],
+ "rc conditions: userExpLevel=registered;unregistered;newcomer;learner;experienced"
+ );
+ }
+
+ public function testFilterUserExpLevelRegisteredUnregistered() {
+ $this->assertConditions(
+ [
+ # expected
+ ],
+ [
+ 'userExpLevel' => 'registered;unregistered',
+ ],
+ "rc conditions: userExpLevel=registered;unregistered"
+ );
+ }
+
+ public function testFilterUserExpLevelRegisteredUnregisteredLearner() {
+ $this->assertConditions(
+ [
+ # expected
+ ],
+ [
+ 'userExpLevel' => 'registered;unregistered;learner',
+ ],
+ "rc conditions: userExpLevel=registered;unregistered;learner"
+ );
+ }
+
+ public function testFilterUserExpLevelAllExperienceLevels() {
+ $this->assertConditions(
+ [
+ # expected
+ 'rc_user != 0',
+ ],
+ [
+ 'userExpLevel' => 'newcomer;learner;experienced',
+ ],
+ "rc conditions: userExpLevel=newcomer;learner;experienced"
+ );
+ }
+
+ public function testFilterUserExpLevelRegistrered() {
+ $this->assertConditions(
+ [
+ # expected
+ 'rc_user != 0',
+ ],
+ [
+ 'userExpLevel' => 'registered',
+ ],
+ "rc conditions: userExpLevel=registered"
+ );
+ }
+
+ public function testFilterUserExpLevelUnregistrered() {
+ $this->assertConditions(
+ [
+ # expected
+ 'rc_user' => 0,
+ ],
+ [
+ 'userExpLevel' => 'unregistered',
+ ],
+ "rc conditions: userExpLevel=unregistered"
+ );
+ }
+
+ public function testFilterUserExpLevelRegistreredOrLearner() {
+ $this->assertConditions(
+ [
+ # expected
+ 'rc_user != 0',
+ ],
+ [
+ 'userExpLevel' => 'registered;learner',
+ ],
+ "rc conditions: userExpLevel=registered;learner"
+ );
+ }
+
+ public function testFilterUserExpLevelUnregistreredOrExperienced() {
+ $conds = $this->buildQuery( [ 'userExpLevel' => 'unregistered;experienced' ] );
+
+ $this->assertRegExp(
+ '/\(rc_user = 0\) OR \(\(user_editcount >= 500\) AND \(user_registration <= \'\d+\'\)\)/',
+ reset( $conds ),
+ "rc conditions: userExpLevel=unregistered;experienced"
+ );
+ }
+
public function testFilterUserExpLevel() {
$now = time();
$this->setMwGlobals( [
$this->fetchUsers( [ 'learner', 'experienced' ], $now ),
'Learner and more experienced'
);
-
- // newcomers, learner, and more experienced
- // TOOD: Fix test. This needs to test that anons are excluded,
- // and right now the join fails.
- /* $this->assertArrayEquals( */
- /* [ */
- /* 'Newcomer1', 'Newcomer2', 'Newcomer3', */
- /* 'Learner1', 'Learner2', 'Learner3', 'Learner4', */
- /* 'Experienced1', */
- /* ], */
- /* $this->fetchUsers( [ 'newcomer', 'learner', 'experienced' ], $now ) */
- /* ); */
}
private function createUsers( $specs, $now ) {
"hideliu" => true,
"userExpLevel" => "newcomer",
],
- "expectedConflicts" => true,
+ "expectedConflicts" => false,
],
[
"parameters" => [
<testsuite name="skins">
<directory>skins</directory>
<directory>structure</directory>
+ <file>suites/ExtensionsTestSuite.php</file>
<file>suites/LessTestSuite.php</file>
</testsuite>
<!-- As there is a class Maintenance, we cannot use the name "maintenance" directly -->
var orgModule = QUnit.module;
QUnit.module = function ( name, localEnv, executeNow ) {
+ if ( QUnit.config.moduleStack.length ) {
+ // When inside a nested module, don't add our Sinon
+ // setup/teardown a second time.
+ return orgModule.apply( this, arguments );
+ }
+
if ( arguments.length === 2 && typeof localEnv === 'function' ) {
executeNow = localEnv;
localEnv = undefined;
localEnv.teardown.call( this );
}
- if ( this.sandbox ) {
- this.sandbox.verifyAndRestore();
- }
+ this.sandbox.verifyAndRestore();
}
}, executeNow );
};
byteLimitTest( {
description: 'Input filter that increases the length',
$input: $( '<input>' ).attr( 'type', 'text' )
- .byteLimit( 10, function ( text ) {
- return 'prefix' + text;
- } ),
+ .byteLimit( 10, function ( text ) {
+ return 'prefix' + text;
+ } ),
sample: simpleSample,
// Prefix adds 6 characters, limit is reached after 4
expected: '1234'
byteLimitTest( {
description: 'Input filter of which the base exceeds the limit',
$input: $( '<input>' ).attr( 'type', 'text' )
- .byteLimit( 3, function ( text ) {
- return 'prefix' + text;
- } ),
+ .byteLimit( 3, function ( text ) {
+ return 'prefix' + text;
+ } ),
sample: simpleSample,
hasLimit: true,
limit: 6, // 'prefix' length
QUnit.test( 'mw-made-collapsible data added', function ( assert ) {
var $collapsible = prepareCollapsible(
- '<div>' + loremIpsum + '</div>'
- );
+ '<div>' + loremIpsum + '</div>'
+ );
assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
} );
QUnit.test( 'mw-collapsible added when missing', function ( assert ) {
var $collapsible = prepareCollapsible(
- '<div>' + loremIpsum + '</div>'
- );
+ '<div>' + loremIpsum + '</div>'
+ );
assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' );
} );
QUnit.test( 'mw-collapsed added when missing', function ( assert ) {
var $collapsible = prepareCollapsible(
'<div>' + loremIpsum + '</div>',
- { collapsed: true }
- );
+ { collapsed: true }
+ );
assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' );
} );
'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C'
] ) !== -1 ) {
assert.ok( true, 'Repond to ' + request.requestBody );
- request.respond( 200, { 'Content-Type': 'application/json' },
- '{ "options": "success" }' );
+ request.respond(
+ 200,
+ { 'Content-Type': 'application/json' },
+ '{ "options": "success" }'
+ );
} else {
assert.ok( false, 'Unexpected request: ' + request.requestBody );
}
'X-Foo': 'Bar'
}
}
- )
- .then( function () {
+ ).then( function () {
assert.equal( test.server.requests[ 0 ].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
return api.postWithToken( 'csrf',
assert.ok( false, 'This parameter cannot be a callback' );
}
);
- } )
- .then( function ( data ) {
+ } ).then( function ( data ) {
assert.equal( data.example, 'quux' );
assert.equal( test.server.requests.length, 2, 'Request made' );
);
assert.equal(
formatParse( 'external-link-plural', 2, 'http://example.org' ),
- 'Foo <a href=\"http://example.org\">two</a> things.',
+ 'Foo <a href="http://example.org">two</a> things.',
'Link is expanded inside an explicit plural form and is not escaped html'
);
assert.equal(
mw.loader.implement( 'test.promise', [ QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mwLoaderTestCallback.js' ) ] );
return mw.loader.using( 'test.promise' )
- .done( function () {
- assert.strictEqual( isAwesomeDone, true, 'test.promise module should\'ve caused isAwesomeDone to be true' );
- delete mw.loader.testCallback;
- } )
- .fail( function () {
- assert.ok( false, 'Error callback fired while loader.using "test.promise" module' );
- } );
+ .done( function () {
+ assert.strictEqual( isAwesomeDone, true, 'test.promise module should\'ve caused isAwesomeDone to be true' );
+ delete mw.loader.testCallback;
+ } )
+ .fail( function () {
+ assert.ok( false, 'Error callback fired while loader.using "test.promise" module' );
+ } );
} );
// Covers mw.loader#sortDependencies (with native Set if available)
assert.ok( /Circular/.test( String( e ) ), 'Detect circular dependency' );
}
)
- .always( done );
+ .always( done );
} );
// @covers mw.loader#sortDependencies (with fallback shim)
assert.ok( /Circular/.test( String( e ) ), 'Detect circular dependency' );
}
)
- .always( done );
+ .always( done );
} );
QUnit.test( '.load() - Error: Circular dependency', function ( assert ) {
}
};
} );
- return mw.loader.using( [ 'test.require1', 'test.require2', 'test.require3', 'test.require4' ] )
- .then( function ( require ) {
+ return mw.loader.using( [ 'test.require1', 'test.require2', 'test.require3', 'test.require4' ] ).then( function ( require ) {
var module1, module2, module3, module4;
module1 = require( 'test.require1' );
-/* eslint comma-dangle: 0 */
-/* eslint no-undef: "error" */
-/* eslint no-console: 0 */
/* eslint-env node */
+/* eslint no-undef: "error" */
+/* eslint-disable no-console, comma-dangle */
'use strict';
const path = require( 'path' );
// with "/", then the base url gets prepended.
baseUrl: (
process.env.MW_SERVER === undefined ?
- 'http://127.0.0.1:8080' :
- process.env.MW_SERVER
+ 'http://127.0.0.1:8080' :
+ process.env.MW_SERVER
) + (
process.env.MW_SCRIPT_PATH === undefined ?
- '/w' :
- process.env.MW_SCRIPT_PATH
+ '/w' :
+ process.env.MW_SCRIPT_PATH
),
//
// Default timeout for all waitFor* commands.