* Revision::setUserIdAndName() was deprecated.
* Access to TitleValue class properties was deprecated, the relevant getters
should be used instead.
+* DifferenceEngine::getDiffBodyCacheKey() is deprecated. Subclasses should
+ override DifferenceEngine::getDiffBodyCacheKeyParams() instead.
+* The deprecated MW_DIFF_VERSION constant was removed.
+ DifferenceEngine::MW_DIFF_VERSION should be used instead.
+* Use of Maintenance::error( $err, $die ) to exit script was deprecated. Use
+ Maintenance::fatalError() instead.
+* Passing a ParserOptions object to OutputPage::parserOptions() is deprecated.
== Compatibility ==
MediaWiki 1.31 requires PHP 5.5.9 or later. There is experimental support for
'CreateAndPromote' => __DIR__ . '/maintenance/createAndPromote.php',
'CreateFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/CreateFileOp.php',
'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php',
+ 'CrhConverter' => __DIR__ . '/languages/classes/LanguageCrh.php',
'CryptHKDF' => __DIR__ . '/includes/libs/CryptHKDF.php',
'CryptRand' => __DIR__ . '/includes/libs/CryptRand.php',
'CssContent' => __DIR__ . '/includes/content/CssContent.php',
'LanguageBs' => __DIR__ . '/languages/classes/LanguageBs.php',
'LanguageCode' => __DIR__ . '/languages/LanguageCode.php',
'LanguageConverter' => __DIR__ . '/languages/LanguageConverter.php',
+ 'LanguageCrh' => __DIR__ . '/languages/classes/LanguageCrh.php',
'LanguageCu' => __DIR__ . '/languages/classes/LanguageCu.php',
'LanguageDsb' => __DIR__ . '/languages/classes/LanguageDsb.php',
'LanguageEn' => __DIR__ . '/languages/classes/LanguageEn.php',
'MediaWiki\\Interwiki\\ClassicInterwikiLookup' => __DIR__ . '/includes/interwiki/ClassicInterwikiLookup.php',
'MediaWiki\\Interwiki\\InterwikiLookup' => __DIR__ . '/includes/interwiki/InterwikiLookup.php',
'MediaWiki\\Interwiki\\InterwikiLookupAdapter' => __DIR__ . '/includes/interwiki/InterwikiLookupAdapter.php',
+ 'MediaWiki\\Languages\\Data\\CrhExceptions' => __DIR__ . '/languages/data/CrhExceptions.php',
'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
'MediaWiki\\Linker\\LinkRenderer' => __DIR__ . '/includes/linker/LinkRenderer.php',
* @param string $heading (optional)
* @return string of HTML representing a box.
*/
- public static function messageBox( $html, $className, $heading = '' ) {
+ private static function messageBox( $html, $className, $heading = '' ) {
if ( $heading ) {
$html = self::element( 'h2', [], $heading ) . $html;
}
* Get/set the ParserOptions object to use for wikitext parsing
*
* @param ParserOptions|null $options Either the ParserOption to use or null to only get the
- * current ParserOption object
+ * current ParserOption object. This parameter is deprecated since 1.31.
* @return ParserOptions
*/
public function parserOptions( $options = null ) {
+ if ( $options !== null ) {
+ wfDeprecated( __METHOD__ . ' with non-null $options', '1.31' );
+ }
+
if ( $options !== null && !empty( $options->isBogus ) ) {
// Someone is trying to set a bogus pre-$wgUser PO. Check if it has
// been changed somehow, and keep it if so.
$defaultPreferences['watchlisttoken'] = [
'type' => 'api',
];
+
+ $tokenButton = new OOUI\ButtonWidget( [
+ 'href' => SpecialPage::getTitleFor( 'ResetTokens' )->getLinkURL( [
+ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText()
+ ] ),
+ 'label' => $context->msg( 'prefs-watchlist-managetokens' )->text(),
+ ] );
$defaultPreferences['watchlisttoken-info'] = [
'type' => 'info',
'section' => 'watchlist/tokenwatchlist',
'label-message' => 'prefs-watchlist-token',
- 'default' => $user->getTokenFromOption( 'watchlisttoken' ),
- 'help-message' => 'prefs-help-watchlist-token2',
- ];
- $defaultPreferences['watchlisttoken-info2'] = [
- 'type' => 'info',
- 'section' => 'watchlist/tokenwatchlist',
+ 'help-message' => 'prefs-help-tokenmanagement',
'raw' => true,
- 'default' => $context->msg( 'prefs-help-watchlist-token2' )->parse(),
+ 'default' => (string)$tokenButton,
];
}
}
*/
const PARAM_ISMULTI_LIMIT2 = 22;
+ /**
+ * (integer) Maximum length of a string in bytes (in UTF-8 encoding).
+ * @since 1.31
+ */
+ const PARAM_MAX_BYTES = 23;
+
+ /**
+ * (integer) Maximum length of a string in characters (unicode codepoints).
+ * @since 1.31
+ */
+ const PARAM_MAX_CHARS = 24;
+
/**@}*/
const ALL_DEFAULT_STRING = '*';
);
}
- // More validation only when choices were not given
- // choices were validated in parseMultiValue()
if ( isset( $value ) ) {
+ // More validation only when choices were not given
+ // choices were validated in parseMultiValue()
if ( !is_array( $type ) ) {
switch ( $type ) {
case 'NULL': // nothing to do
$value = array_unique( $value );
}
+ if ( in_array( $type, [ 'NULL', 'string', 'text', 'password' ], true ) ) {
+ foreach ( (array)$value as $val ) {
+ if ( isset( $paramSettings[self::PARAM_MAX_BYTES] )
+ && strlen( $val ) > $paramSettings[self::PARAM_MAX_BYTES]
+ ) {
+ $this->dieWithError( [ 'apierror-maxbytes', $encParamName,
+ $paramSettings[self::PARAM_MAX_BYTES] ] );
+ }
+ if ( isset( $paramSettings[self::PARAM_MAX_CHARS] )
+ && mb_strlen( $val, 'UTF-8' ) > $paramSettings[self::PARAM_MAX_CHARS]
+ ) {
+ $this->dieWithError( [ 'apierror-maxchars', $encParamName,
+ $paramSettings[self::PARAM_MAX_CHARS] ] );
+ }
+ }
+ }
+
// Set a warning if a deprecated parameter has been passed
if ( $deprecated && $value !== false ) {
$feature = $encParamName;
}
}
+ if ( isset( $settings[self::PARAM_MAX_BYTES] ) ) {
+ $info[] = $context->msg( 'api-help-param-maxbytes' )
+ ->numParams( $settings[self::PARAM_MAX_BYTES] );
+ }
+ if ( isset( $settings[self::PARAM_MAX_CHARS] ) ) {
+ $info[] = $context->msg( 'api-help-param-maxchars' )
+ ->numParams( $settings[self::PARAM_MAX_CHARS] );
+ }
+
// Add default
$default = isset( $settings[ApiBase::PARAM_DFLT] )
? $settings[ApiBase::PARAM_DFLT]
if ( !empty( $settings[ApiBase::PARAM_RANGE_ENFORCE] ) ) {
$item['enforcerange'] = true;
}
+ if ( isset( $settings[self::PARAM_MAX_BYTES] ) ) {
+ $item['maxbytes'] = $settings[self::PARAM_MAX_BYTES];
+ }
+ if ( isset( $settings[self::PARAM_MAX_CHARS] ) ) {
+ $item['maxchars'] = $settings[self::PARAM_MAX_CHARS];
+ }
if ( !empty( $settings[ApiBase::PARAM_DEPRECATED_VALUES] ) ) {
$deprecatedValues = array_keys( $settings[ApiBase::PARAM_DEPRECATED_VALUES] );
if ( is_array( $item['type'] ) ) {
$title = $page->getTitle();
$key = self::getStashKey( $title, self::getContentHash( $content ), $user );
- // Use the master DB for fast blocking locks
+ // Use the master DB to allow for fast blocking locks on the "save path" where this
+ // value might actually be used to complete a page edit. If the edit submission request
+ // happens before this edit stash requests finishes, then the submission will block until
+ // the stash request finishes parsing. For the lock acquisition below, there is not much
+ // need to duplicate parsing of the same content/user/summary bundle, so try to avoid
+ // blocking at all here.
$dbw = wfGetDB( DB_MASTER );
- if ( !$dbw->lock( $key, __METHOD__, 1 ) ) {
+ if ( !$dbw->lock( $key, __METHOD__, 0 ) ) {
// De-duplicate requests on the same key
return self::ERROR_BUSY;
}
"api-help-param-disabled-in-miser-mode": "Deaktiviert aufgrund des [[mw:Special:MyLanguage/Manual:$wgMiserMode|Miser-Modus]].",
"api-help-param-continue": "Falls weitere Ergebnisse verfügbar sind, dies zum Fortfahren verwenden.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(keine Beschreibung)</span>",
+ "api-help-param-maxbytes": "Kann nicht länger sein als {{PLURAL:$1|ein Byte|$1 Bytes}}.",
+ "api-help-param-maxchars": "Kann nicht länger sein als {{PLURAL:$1|ein|$1}} Zeichen.",
"api-help-examples": "{{PLURAL:$1|Beispiel|Beispiele}}:",
"api-help-permissions": "{{PLURAL:$1|Berechtigung|Berechtigungen}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|Gewährt an}}: $2",
"apierror-invalid-file-key": "Kein gültiger Dateischlüssel.",
"apierror-invalidsection": "Der Parameter <var>section</var> muss eine gültige Abschnittskennung oder <kbd>new</kbd> sein.",
"apierror-invaliduserid": "Die Benutzerkennung <var>$1</var> ist nicht gültig.",
+ "apierror-maxbytes": "Der Parameter <var>$1</var> kann nicht länger sein als {{PLURAL:$2|ein Byte|$2 Bytes}}",
+ "apierror-maxchars": "Der Parameter <var>$1</var> kann nicht länger sein als {{PLURAL:$2|ein|$2}} Zeichen",
"apierror-nosuchsection": "Es gibt keinen Abschnitt $1.",
"apierror-nosuchuserid": "Es gibt keinen Benutzer mit der Kennung $1.",
"apierror-offline": "Aufgrund von Problemen bei der Netzwerkverbindung kannst du nicht weitermachen. Stelle sicher, dass du eine funktionierende Internetverbindung hast und versuche es erneut.",
"api-help-param-direction": "In which direction to enumerate:\n;newer:List oldest first. Note: $1start has to be before $1end.\n;older:List newest first (default). Note: $1start has to be later than $1end.",
"api-help-param-continue": "When more results are available, use this to continue.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(no description)</span>",
+ "api-help-param-maxbytes": "Cannot be longer than $1 {{PLURAL:$1|byte|bytes}}.",
+ "api-help-param-maxchars": "Cannot be longer than $1 {{PLURAL:$1|character|characters}}.",
"api-help-examples": "{{PLURAL:$1|Example|Examples}}:",
"api-help-permissions": "{{PLURAL:$1|Permission|Permissions}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|Granted to}}: $2",
"apierror-invalidurlparam": "Invalid value for <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
"apierror-invaliduser": "Invalid username \"$1\".",
"apierror-invaliduserid": "User ID <var>$1</var> is not valid.",
+ "apierror-maxbytes": "Parameter <var>$1</var> cannot be longer than $2 {{PLURAL:$2|byte|bytes}}",
+ "apierror-maxchars": "Parameter <var>$1</var> cannot be longer than $2 {{PLURAL:$2|character|characters}}",
"apierror-maxlag-generic": "Waiting for a database server: $1 {{PLURAL:$1|second|seconds}} lagged.",
"apierror-maxlag": "Waiting for $2: $1 {{PLURAL:$1|second|seconds}} lagged.",
"apierror-mimesearchdisabled": "MIME search is disabled in Miser Mode.",
"api-help-param-direction": "Dans quelle direction énumérer :\n;newer:Lister les plus anciens en premier. Note : $1start doit être avant $1end.\n;older:Lister les nouveaux en premier (par défaut). Note : $1start doit être postérieur à $1end.",
"api-help-param-continue": "Quand plus de résultats sont disponibles, utiliser cela pour continuer.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(aucune description)</span>",
+ "api-help-param-maxbytes": "Ne peut excéder $1 octet{{PLURAL:$1||s}}.",
+ "api-help-param-maxchars": "Ne peut excéder $1 caractères{{PLURAL:$1||s}}.",
"api-help-examples": "{{PLURAL:$1|Exemple|Exemples}} :",
"api-help-permissions": "{{PLURAL:$1|Droit|Droits}} :",
"api-help-permissions-granted-to": "{{PLURAL:$1|Accordé à}} : $2",
"apierror-invalidurlparam": "Valeur non valide pour <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
"apierror-invaliduser": "Nom d'utilisateur invalide \"$1\".",
"apierror-invaliduserid": "L'ID d'utilisateur <var>$1</var> n'est pas valide.",
+ "apierror-maxbytes": "Le paramètre <var>$1</var> ne peut excéder $2 octets{{PLURAL:$2||s}}",
+ "apierror-maxchars": "Le paramètre <var>$1</var> ne peut excéder $2 catactères{{PLURAL:$2||s}}",
"apierror-maxlag-generic": "Attente d’un serveur de base de données : $1 {{PLURAL:$1|seconde|secondes}} de délai.",
"apierror-maxlag": "Attente de $2 : $1 {{PLURAL:$1|seconed|secondes}} de délai.",
"apierror-mimesearchdisabled": "La recherche MIME est désactivée en mode Misère.",
"api-help-param-token": "Un token \"$1\" recuperato da [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
"api-help-param-continue": "Quando più risultati sono disponibili, usa questo per continuare.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(nessuna descrizione)</span>",
+ "api-help-param-maxbytes": "Non può essere più lungo di $1 {{PLURAL:$1|byte}}.",
+ "api-help-param-maxchars": "Non può essere più lungo di $1 {{PLURAL:$1|carattere|caratteri}}.",
"api-help-examples": "{{PLURAL:$1|Esempio|Esempi}}:",
"api-help-permissions": "{{PLURAL:$1|Permesso|Permessi}}:",
"api-help-open-in-apisandbox": "<small>[apri in una sandbox]</small>",
"api-help-authmanagerhelper-additional-params": "Questo modulo accetta parametri aggiuntivi a seconda delle richieste di autenticazione disponibili. Utilizza <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> con <kbd>amirequestsfor=$1</kbd> (o una precedente risposta da questo modulo, se applicabile) per determinare le richieste disponibili e i campi usati da queste.",
"apierror-invalidoldimage": "Il parametro <var>oldimage</var> ha un formato non valido.",
"apierror-invaliduserid": "L'ID utente <var>$1</var> non è valido.",
+ "apierror-maxbytes": "Il parametro <var>$1</var> non può essere più lungo di $2 {{PLURAL:$2|byte}}",
+ "apierror-maxchars": "Il parametro <var>$1</var> non può essere più lungo di $2 {{PLURAL:$2|carattere|caratteri}}",
"apierror-nosuchuserid": "Non c'è alcun utente con ID $1.",
"apierror-timeout": "Il server non ha risposto entro il tempo previsto.",
"api-credits-header": "Crediti"
"api-help-param-token-webui": "호환성을 위해, 웹 UI에 사용된 토큰도 허용합니다.",
"api-help-param-continue": "더 많은 결과를 이용할 수 있을 때, 계속하려면 이것을 사용하십시오.",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(설명 없음)</span>",
+ "api-help-param-maxbytes": "$1{{PLURAL:$1|바이트}}를 초과할 수 없습니다.",
+ "api-help-param-maxchars": "$1{{PLURAL:$1|자}}를 초과할 수 없습니다.",
"api-help-examples": "{{PLURAL:$1|예시}}:",
"api-help-permissions": "{{PLURAL:$1|권한}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|다음 그룹에 부여됨}}: $2",
"apierror-invalidtitle": "잘못된 제목 \"$1\".",
"apierror-invaliduser": "잘못된 사용자 이름 \"$1\".",
"apierror-invaliduserid": "<var>$1</var> 사용자 ID는 유효하지 않습니다.",
+ "apierror-maxbytes": "<var>$1</var> 변수는 $2{{PLURAL:$2|바이트}}를 초과할 수 없습니다",
+ "apierror-maxchars": "<var>$1</var> 변수는 $2{{PLURAL:$2|자}}를 초과할 수 없습니다",
"apierror-maxlag-generic": "데이터베이스 서버 대기 중: $1 {{PLURAL:$1|초}} 지연되었습니다.",
"apierror-maxlag": "$2 대기 중: $1 {{PLURAL:$1|초}} 지연되었습니다.",
"apierror-missingcontent-revid": "ID $1 판에 해당하는 내용이 없습니다.",
"api-help-param-direction": "A direção da enumeração:\n;newer:Listar o mais antigo primeiro. Nota: $1start tem de estar antes de $1end.\n;older:Listar o mais recente primeiro (padrão). Nota: $1start tem de estar depois de $1end.",
"api-help-param-continue": "Quando houver mais resultados disponíveis, usar isto para continuar",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(sem descrição)</span>",
+ "api-help-param-maxbytes": "Não pode exceder $1 {{PLURAL:$1|byte|bytes}}.",
+ "api-help-param-maxchars": "Não pode exceder $1 {{PLURAL:$1|carácter|caracteres}}.",
"api-help-examples": "{{PLURAL:$1|Exemplo|Exemplos}}:",
"api-help-permissions": "{{PLURAL:$1|Permissão|Permissões}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|Concedida a|Concedidas a}}: $2",
"apierror-invalidurlparam": "Valor inválido para <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
"apierror-invaliduser": "Nome de utilizador inválido \"$1\".",
"apierror-invaliduserid": "O identificador de utilizador <var>$1</var> não é válido.",
+ "apierror-maxbytes": "O parâmetro <var>$1</var> não pode exceder $2 {{PLURAL:$2|byte|bytes}}",
+ "apierror-maxchars": "O parâmetro <var>$1</var> não pode exceder $2 {{PLURAL:$2|carácter|caracteres}}",
"apierror-maxlag-generic": "À espera de um servidor de base de dados: $1 {{PLURAL:$1|segundo|segundos}} de atraso.",
"apierror-maxlag": "À espera de $2: $1 {{PLURAL:$1|segundo|segundos}} de atraso.",
"apierror-mimesearchdisabled": "A pesquisa MIME é desativada no modo avarento.",
"api-help-param-direction": "{{doc-apihelp-param|description=any standard \"dir\" parameter|noseealso=1}}",
"api-help-param-continue": "{{doc-apihelp-param|description=any standard \"continue\" parameter, or other parameter with the same semantics|noseealso=1}}",
"api-help-param-no-description": "Displayed on API parameters that lack any description",
+ "api-help-param-maxbytes": "Used to display the maximum allowed length of a parameter, in bytes.",
+ "api-help-param-maxchars": "Used to display the maximum allowed length of a parameter, in characters.",
"api-help-examples": "Label for the API help examples section\n\nParameters:\n* $1 - Number of examples to be displayed\n{{Identical|Example}}",
"api-help-permissions": "Label for the \"permissions\" section in the main module's help output.\n\nParameters:\n* $1 - Number of permissions displayed\n{{Identical|Permission}}",
"api-help-permissions-granted-to": "Used to introduce the list of groups each permission is assigned to.\n\nParameters:\n* $1 - Number of groups\n* $2 - List of group names, comma-separated",
"apierror-invalidurlparam": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".\n* $2 - Key\n* $3 - Value.",
"apierror-invaliduser": "{{doc-apierror}}\n\nParameters:\n* $1 - User name that is invalid.",
"apierror-invaliduserid": "{{doc-apierror}}",
+ "apierror-maxbytes": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Maximum allowed bytes.",
+ "apierror-maxchars": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n* $2 - Maximum allowed characters.",
"apierror-maxlag-generic": "{{doc-apierror}}\n\nParameters:\n* $1 - Database is lag in seconds.",
"apierror-maxlag": "{{doc-apierror}}\n\nParameters:\n* $1 - Database lag in seconds.\n* $2 - Database server that is lagged.",
"apierror-mimesearchdisabled": "{{doc-apierror}}",
"api-help-param-direction": "列举的方向:\n;newer:最早的优先。注意:$1start应早于$1end。\n;older:最新的优先(默认)。注意:$1start应晚于$1end。",
"api-help-param-continue": "当更多结果可用时,使用这个继续。",
"api-help-param-no-description": "<span class=\"apihelp-empty\">(没有说明)</span>",
+ "api-help-param-maxbytes": "不能超过$1{{PLURAL:$1|字节}}。",
+ "api-help-param-maxchars": "不能超过$1个{{PLURAL:$1|字符}}。",
"api-help-examples": "{{PLURAL:$1|例子}}:",
"api-help-permissions": "{{PLURAL:$1|权限}}:",
"api-help-permissions-granted-to": "{{PLURAL:$1|授予}}:$2",
"apierror-invalidurlparam": "<var>$1urlparam</var>的值无效(<kbd>$2=$3</kbd>)。",
"apierror-invaliduser": "无效用户名“$1”。",
"apierror-invaliduserid": "用户ID<var>$1</var>无效。",
+ "apierror-maxbytes": "参数<var>$1</var>不能超过$2{{PLURAL:$2|字节}}",
+ "apierror-maxchars": "参数<var>$1</var>不能超过$2个{{PLURAL:$2|字符}}",
"apierror-maxlag-generic": "正在等待数据库服务器:已延迟$1{{PLURAL:$1|秒}}。",
"apierror-maxlag": "正在等待$2:已延迟$1{{PLURAL:$1|秒}}。",
"apierror-mimesearchdisabled": "MIME搜索在Miser模式中被禁用。",
return '';
}
$cache = $this->watchMsgCache;
- return $cache->getWithSetCallback( $count, $cache::TTL_INDEFINITE,
+ return $cache->getWithSetCallback(
+ $cache->makeKey( 'watching-users-msg', $count ),
+ $cache::TTL_INDEFINITE,
function () use ( $count ) {
return $this->msg( 'number_of_watching_users_RCview' )
->numParams( $count )->escaped();
use MediaWiki\MediaWikiServices;
use MediaWiki\Shell\Shell;
-/** @deprecated use class constant instead */
-define( 'MW_DIFF_VERSION', '1.11a' );
-
/**
* @todo document
* @ingroup DifferenceEngine
* fixes important bugs or such to force cached diff views to
* clear.
*/
- const DIFF_VERSION = MW_DIFF_VERSION;
+ const DIFF_VERSION = '1.12';
/** @var int */
public $mOldid;
$key = false;
$cache = ObjectCache::getMainWANInstance();
if ( $this->mOldid && $this->mNewid ) {
+ // Check if subclass is still using the old way
+ // for backwards-compatibility
$key = $this->getDiffBodyCacheKey();
+ if ( $key === null ) {
+ $key = call_user_func_array(
+ [ $cache, 'makeKey' ],
+ $this->getDiffBodyCacheKeyParams()
+ );
+ }
// Try cache
if ( !$this->mRefreshCache ) {
$difftext = $cache->get( $key );
if ( $difftext ) {
wfIncrStats( 'diff_cache.hit' );
- $difftext = $this->localiseLineNumbers( $difftext );
+ $difftext = $this->localiseDiff( $difftext );
$difftext .= "\n<!-- diff cache key $key -->\n";
return $difftext;
} else {
wfIncrStats( 'diff_cache.uncacheable' );
}
- // Replace line numbers with the text in the user's language
+ // localise line numbers and title attribute text
if ( $difftext !== false ) {
- $difftext = $this->localiseLineNumbers( $difftext );
+ $difftext = $this->localiseDiff( $difftext );
}
return $difftext;
/**
* Returns the cache key for diff body text or content.
*
+ * @deprecated since 1.31, use getDiffBodyCacheKeyParams() instead
* @since 1.23
*
* @throws MWException
- * @return string
+ * @return string|null
*/
protected function getDiffBodyCacheKey() {
+ return null;
+ }
+
+ /**
+ * Get the cache key parameters
+ *
+ * Subclasses can replace the first element in the array to something
+ * more specific to the type of diff (e.g. "inline-diff"), or append
+ * if the cache should vary on more things. Overriding entirely should
+ * be avoided.
+ *
+ * @since 1.31
+ *
+ * @return array
+ * @throws MWException
+ */
+ protected function getDiffBodyCacheKeyParams() {
if ( !$this->mOldid || !$this->mNewid ) {
throw new MWException( 'mOldid and mNewid must be set to get diff cache key.' );
}
- return wfMemcKey( 'diff', 'version', self::DIFF_VERSION,
- 'oldid', $this->mOldid, 'newid', $this->mNewid );
+ $engine = $this->getEngine();
+ $params = [
+ 'diff',
+ $engine,
+ self::DIFF_VERSION,
+ "old-{$this->mOldid}",
+ "rev-{$this->mNewid}"
+ ];
+
+ if ( $engine === 'wikidiff2' ) {
+ $params[] = phpversion( 'wikidiff2' );
+ $params[] = $this->getConfig()->get( 'WikiDiff2MovedParagraphDetectionCutoff' );
+ }
+
+ return $params;
}
/**
}
/**
- * Generates diff, to be wrapped internally in a logging/instrumentation
+ * Process $wgExternalDiffEngine and get a sane, usable engine
*
- * @param string $otext Old text, must be already segmented
- * @param string $ntext New text, must be already segmented
- * @return bool|string
- * @throws Exception
+ * @return bool|string 'wikidiff2', path to an executable, or false
*/
- protected function textDiff( $otext, $ntext ) {
- global $wgExternalDiffEngine, $wgContLang;
-
- $otext = str_replace( "\r\n", "\n", $otext );
- $ntext = str_replace( "\r\n", "\n", $ntext );
-
+ private function getEngine() {
+ global $wgExternalDiffEngine;
+ // We use the global here instead of Config because we write to the value,
+ // and Config is not mutable.
if ( $wgExternalDiffEngine == 'wikidiff' || $wgExternalDiffEngine == 'wikidiff3' ) {
wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27' );
$wgExternalDiffEngine = false;
$wgExternalDiffEngine = false;
}
+ if ( is_string( $wgExternalDiffEngine ) && is_executable( $wgExternalDiffEngine ) ) {
+ return $wgExternalDiffEngine;
+ } elseif ( $wgExternalDiffEngine === false && function_exists( 'wikidiff2_do_diff' ) ) {
+ return 'wikidiff2';
+ } else {
+ // Native PHP
+ return false;
+ }
+ }
+
+ /**
+ * Generates diff, to be wrapped internally in a logging/instrumentation
+ *
+ * @param string $otext Old text, must be already segmented
+ * @param string $ntext New text, must be already segmented
+ * @return bool|string
+ */
+ protected function textDiff( $otext, $ntext ) {
+ global $wgContLang;
+
+ $otext = str_replace( "\r\n", "\n", $otext );
+ $ntext = str_replace( "\r\n", "\n", $ntext );
+
+ $engine = $this->getEngine();
+
// 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 ) {
+ if ( $engine === 'wikidiff2' ) {
$wikidiff2Version = phpversion( 'wikidiff2' );
if (
$wikidiff2Version !== false &&
$text .= $this->debug( 'wikidiff2' );
return $text;
- } elseif ( $wgExternalDiffEngine !== false && is_executable( $wgExternalDiffEngine ) ) {
+ } elseif ( $engine !== false ) {
# Diff via the shell
$tmpDir = wfTempDir();
$tempName1 = tempnam( $tmpDir, 'diff_' );
fwrite( $tempFile2, $ntext );
fclose( $tempFile1 );
fclose( $tempFile2 );
- $cmd = [ $wgExternalDiffEngine, $tempName1, $tempName2 ];
+ $cmd = [ $engine, $tempName1, $tempName2 ];
$result = Shell::command( $cmd )
->execute();
$exitCode = $result->getExitCode();
);
}
$difftext = $result->getStdout();
- $difftext .= $this->debug( "external $wgExternalDiffEngine" );
+ $difftext .= $this->debug( "external $engine" );
unlink( $tempName1 );
unlink( $tempName2 );
" -->\n";
}
+ /**
+ * Localise diff output
+ *
+ * @param string $text
+ * @return string
+ */
+ private function localiseDiff( $text ) {
+ $text = $this->localiseLineNumbers( $text );
+ if ( $this->getEngine() === 'wikidiff2' &&
+ version_compare( phpversion( 'wikidiff2' ), '1.5.1', '>=' )
+ ) {
+ $text = $this->addLocalisedTitleTooltips( $text );
+ }
+ return $text;
+ }
+
/**
* Replace line numbers with the text in the user's language
*
return $this->msg( 'lineno' )->numParams( $matches[1] )->escaped();
}
+ /**
+ * Add title attributes for tooltips on moved paragraph indicators
+ *
+ * @param string $text
+ * @return string
+ */
+ private function addLocalisedTitleTooltips( $text ) {
+ return preg_replace_callback(
+ '/class="mw-diff-movedpara-(left|right)"/',
+ [ $this, 'addLocalisedTitleTooltipsCb' ],
+ $text
+ );
+ }
+
+ /**
+ * @param array $matches
+ * @return string
+ */
+ private function addLocalisedTitleTooltipsCb( array $matches ) {
+ $key = $matches[1] === 'right' ?
+ 'diff-paragraph-moved-toold' :
+ 'diff-paragraph-moved-tonew';
+ return $matches[0] . ' title="' . $this->msg( $key )->escaped() . '"';
+ }
+
/**
* If there are revisions between the ones being compared, return a note saying so.
*
*/
class InstallDocFormatter {
- static function format( $text ) {
+ public static function format( $text ) {
$obj = new self( $text );
return $obj->execute();
"config-session-expired": "Os seus dados de sessão parecem ter expirado.\nAs sessões estão configuradas para uma duração de $1.\nPode aumentar esta duração configurando <code>session.gc_maxlifetime</code> no php.ini.\nReinicie o processo de instalação.",
"config-no-session": "Os seus dados de sessão foram perdidos!\nVerifique o seu php.ini e certifique-se de que em <code>session.save_path</code> está definido um diretório apropriado.",
"config-your-language": "A sua língua:",
- "config-your-language-help": "Selecione o idioma que será usado durante o processo de instalação.",
+ "config-your-language-help": "Selecione a língua que será usada durante o processo de instalação.",
"config-wiki-language": "Língua da wiki:",
"config-wiki-language-help": "Selecione a língua que será predominante na wiki.",
"config-back": "← Voltar",
/**
* Job to add recent change entries mentioning category membership changes
*
+ * This allows users to easily scan categories for recent page membership changes
+ *
* Parameters include:
* - pageId : page ID
* - revTimestamp : timestamp of the triggering revision
return false; // deleted?
}
+ // Cut down on the time spent in safeWaitForMasterPos() in the critical section
+ $dbr = $lb->getConnection( DB_REPLICA, [ 'recentchanges' ] );
+ if ( !$lb->safeWaitForMasterPos( $dbr ) ) {
+ $this->setLastError( "Timed out while pre-waiting for replica DB to catch up" );
+ return false;
+ }
+
// Use a named lock so that jobs for this page see each others' changes
$lockKey = "CategoryMembershipUpdates:{$page->getId()}";
$scopedLock = $dbw->getScopedLockAndFlush( $lockKey, __METHOD__, 3 );
return false;
}
- $dbr = $lb->getConnection( DB_REPLICA, [ 'recentchanges' ] );
- // Wait till the replica DB is caught up so that jobs for this page see each others' changes
+ // Wait till replica DB is caught up so that jobs for this page see each others' changes
if ( !$lb->safeWaitForMasterPos( $dbr ) ) {
$this->setLastError( "Timed out while waiting for replica DB to catch up" );
return false;
// between COMMIT and actual enqueueing of the CategoryMembershipChangeJob job.
$cutoffUnix -= self::ENQUEUE_FUDGE_SEC;
- // Get the newest revision that has a SRC_CATEGORIZE row...
+ // Get the newest page revision that has a SRC_CATEGORIZE row.
+ // Assume that category changes before it were already handled.
$row = $dbr->selectRow(
- [ 'revision', 'recentchanges' ],
+ 'revision',
[ 'rev_timestamp', 'rev_id' ],
[
'rev_page' => $page->getId(),
- 'rev_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) )
- ],
- __METHOD__,
- [ 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ],
- [
- 'recentchanges' => [
- 'INNER JOIN',
+ 'rev_timestamp >= ' . $dbr->addQuotes( $dbr->timestamp( $cutoffUnix ) ),
+ 'EXISTS (' . $dbr->selectSQLText(
+ 'recentchanges',
+ '1',
[
'rc_this_oldid = rev_id',
'rc_source' => RecentChange::SRC_CATEGORIZE,
// Allow rc_cur_id or rc_timestamp index usage
'rc_cur_id = rev_page',
- 'rc_timestamp >= rev_timestamp'
+ 'rc_timestamp = rev_timestamp'
]
- ]
- ]
+ ) . ')'
+ ],
+ __METHOD__,
+ [ 'ORDER BY' => 'rev_timestamp DESC, rev_id DESC' ]
);
// Only consider revisions newer than any such revision
if ( $row ) {
* Make a global cache key.
*
* @since 1.27
- * @param string $keys,... Key component (starting with a key collection name)
+ * @param string $class Key class
+ * @param string $component [optional] Key component (starting with a key collection name)
* @return string Colon-delimited list of $keyspace followed by escaped components of $args
*/
- public function makeGlobalKey() {
+ public function makeGlobalKey( $class, $component = null ) {
return $this->makeKeyInternal( 'global', func_get_args() );
}
* Make a cache key, scoped to this instance's keyspace.
*
* @since 1.27
- * @param string $keys,... Key component (starting with a key collection name)
+ * @param string $class Key class
+ * @param string $component [optional] Key component (starting with a key collection name)
* @return string Colon-delimited list of $keyspace followed by escaped components of $args
*/
- public function makeKey() {
+ public function makeKey( $class, $component = null ) {
return $this->makeKeyInternal( $this->keyspace, func_get_args() );
}
return $this->backend->deleteObjectsExpiringBefore( $date, $progressCallback );
}
- public function makeKey() {
+ public function makeKey( $class, $component = null ) {
return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
}
- public function makeGlobalKey() {
+ public function makeGlobalKey( $class, $component = null ) {
return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
}
);
if ( $charsLeft < 0 ) {
- return $keyspace . ':##' . md5( implode( ':', $args ) );
+ return $keyspace . ':BagOStuff-long-key:##' . md5( implode( ':', $args ) );
}
return $keyspace . ':' . implode( ':', $args );
return $ret;
}
- public function makeKey() {
+ public function makeKey( $class, $component = null ) {
return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
}
- public function makeGlobalKey() {
+ public function makeGlobalKey( $class, $component = null ) {
return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
}
}
const TTL_LAGGED = 30;
/** Idiom for delete() for "no hold-off" */
const HOLDOFF_NONE = 0;
+ /** Idiom for set() for "do not augment the storage medium TTL" */
+ const STALE_TTL_NONE = 0;
+
/** Idiom for getWithSetCallback() for "no minimum required as-of timestamp" */
const MIN_TIMESTAMP_NONE = 0.0;
* @return WANObjectCache
*/
public static function newEmpty() {
- return new self( [
+ return new static( [
'cache' => new EmptyBagOStuff(),
'pool' => 'empty'
] );
$wrappedValues += $this->cache->getMulti( $keysGet );
}
// Time used to compare/init "check" keys (derived after getMulti() to be pessimistic)
- $now = microtime( true );
+ $now = $this->getCurrentTime();
// Collect timestamps from all "check" keys
$purgeValuesForAll = $this->processCheckKeys( $checkKeysForAll, $wrappedValues, $now );
* they certainly should not see ones that ended up getting rolled back.
* Default: false
* - lockTSE : if excessive replication/snapshot lag is detected, then store the value
- * with this TTL and flag it as stale. This is only useful if the reads for
- * this key use getWithSetCallback() with "lockTSE" set.
+ * with this TTL and flag it as stale. This is only useful if the reads for this key
+ * use getWithSetCallback() with "lockTSE" set. Note that if "staleTTL" is set
+ * then it will still add on to this TTL in the excessive lag scenario.
* Default: WANObjectCache::TSE_NONE
* - staleTTL : Seconds to keep the key around if it is stale. The get()/getMulti()
* methods return such stale values with a $curTTL of 0, and getWithSetCallback()
* will call the regeneration callback in such cases, passing in the old value
* and its as-of time to the callback. This is useful if adaptiveTTL() is used
* on the old value's as-of time when it is verified as still being correct.
- * Default: 0.
+ * Default: WANObjectCache::STALE_TTL_NONE.
* @note Options added in 1.28: staleTTL
* @return bool Success
*/
final public function set( $key, $value, $ttl = 0, array $opts = [] ) {
- $now = microtime( true );
+ $now = $this->getCurrentTime();
$lockTSE = isset( $opts['lockTSE'] ) ? $opts['lockTSE'] : self::TSE_NONE;
+ $staleTTL = isset( $opts['staleTTL'] ) ? $opts['staleTTL'] : self::STALE_TTL_NONE;
$age = isset( $opts['since'] ) ? max( 0, $now - $opts['since'] ) : 0;
$lag = isset( $opts['lag'] ) ? $opts['lag'] : 0;
- $staleTTL = isset( $opts['staleTTL'] ) ? $opts['staleTTL'] : 0;
// Do not cache potentially uncommitted data as it might get rolled back
if ( !empty( $opts['pending'] ) ) {
$time = $purge[self::FLD_TIME];
} else {
// Casting assures identical floats for the next getCheckKeyTime() calls
- $now = (string)microtime( true );
+ $now = (string)$this->getCurrentTime();
$this->cache->add( $key,
$this->makePurgeValue( $now, self::HOLDOFF_TTL ),
self::CHECK_KEY_TTL
// Value existed before with a different version; use variant key.
// Reflect purges to $key by requiring that this key value be newer.
$value = $this->doGetWithSetCallback(
- 'cache-variant:' . md5( $key ) . ":$version",
+ $this->makeGlobalKey( 'WANCache-key-variant', md5( $key ), $version ),
$ttl,
$callback,
// Regenerate value if not newer than $key
$cValue = $this->get( $key, $curTTL, $checkKeys, $asOf ); // current value
$value = $cValue; // return value
- $preCallbackTime = microtime( true );
+ $preCallbackTime = $this->getCurrentTime();
// Determine if a cached value regeneration is needed or desired
if ( $value !== false
&& $curTTL > 0
// so use a special INTERIM key to pass the new value around threads.
if ( ( $isTombstone && $lockTSE > 0 ) && $valueIsCacheable ) {
$tempTTL = max( 1, (int)$lockTSE ); // set() expects seconds
- $newAsOf = microtime( true );
+ $newAsOf = $this->getCurrentTime();
$wrapped = $this->wrap( $value, $tempTTL, $newAsOf );
// Avoid using set() to avoid pointless mcrouter broadcasting
$this->setInterimValue( $key, $wrapped, $tempTTL );
*/
protected function getInterimValue( $key, $versioned, $minTime, &$asOf ) {
$wrapped = $this->cache->get( self::INTERIM_KEY_PREFIX . $key );
- list( $value ) = $this->unwrap( $wrapped, microtime( true ) );
+ list( $value ) = $this->unwrap( $wrapped, $this->getCurrentTime() );
if ( $value !== false && $this->isValid( $value, $versioned, $asOf, $minTime ) ) {
$asOf = $wrapped[self::FLD_TIME];
/**
* @see BagOStuff::makeKey()
- * @param string $keys,... Key component (starting with a key collection name)
+ * @param string $class Key class
+ * @param string $component [optional] Key component (starting with a key collection name)
* @return string Colon-delimited list of $keyspace followed by escaped components of $args
* @since 1.27
*/
- public function makeKey() {
+ public function makeKey( $class, $component = null ) {
return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
}
/**
* @see BagOStuff::makeGlobalKey()
- * @param string $keys,... Key component (starting with a key collection name)
+ * @param string $class Key class
+ * @param string $component [optional] Key component (starting with a key collection name)
* @return string Colon-delimited list of $keyspace followed by escaped components of $args
* @since 1.27
*/
- public function makeGlobalKey() {
+ public function makeGlobalKey( $class, $component = null ) {
return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
}
if ( $this->purgeRelayer instanceof EventRelayerNull ) {
// This handles the mcrouter and the single-DC case
$ok = $this->cache->set( $key,
- $this->makePurgeValue( microtime( true ), self::HOLDOFF_NONE ),
+ $this->makePurgeValue( $this->getCurrentTime(), self::HOLDOFF_NONE ),
$ttl
);
} else {
* @return bool
*/
protected function worthRefreshExpiring( $curTTL, $lowTTL ) {
- if ( $curTTL >= $lowTTL ) {
+ if ( $lowTTL <= 0 ) {
+ return false;
+ } elseif ( $curTTL >= $lowTTL ) {
return false;
} elseif ( $curTTL <= 0 ) {
return true;
* @return bool
*/
protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh, $now ) {
+ if ( $ageNew < 0 || $timeTillRefresh <= 0 ) {
+ return false;
+ }
+
$age = $now - $asOf;
$timeOld = $age - $ageNew;
if ( $timeOld <= 0 ) {
return isset( $parts[1] ) ? $parts[1] : $parts[0]; // sanity
}
+ /**
+ * @return float UNIX timestamp
+ * @codeCoverageIgnore
+ */
+ protected function getCurrentTime() {
+ return microtime( true );
+ }
+
/**
* @param string $value Wrapped value like "PURGED:<timestamp>:<holdoff>"
* @return array|bool Array containing a UNIX timestamp (float) and holdoff period (integer),
/** @var string */
private $lastSection;
+ /** @var int */
+ private $maxLag = self::MAX_LAG_DEFAULT;
+
+ /** @var int Default 'maxLag' when unspecified */
+ const MAX_LAG_DEFAULT = 10;
+
/**
* @see LBFactory::__construct()
*
* storage cluster.
* - masterTemplateOverrides Server configuration map overrides for all master servers.
* - loadMonitorClass Name of the LoadMonitor class to always use.
+ * - maxLag Avoid replica DBs with more lag than this many seconds.
* - readOnlyBySection A map of section name to read-only message.
* Missing or false for read/write.
*/
$optional = [ 'groupLoadsBySection', 'groupLoadsByDB', 'hostsByName',
'externalLoads', 'externalTemplateOverrides', 'templateOverridesByServer',
'templateOverridesByCluster', 'templateOverridesBySection', 'masterTemplateOverrides',
- 'readOnlyBySection', 'loadMonitorClass' ];
+ 'readOnlyBySection', 'maxLag', 'loadMonitorClass' ];
foreach ( $required as $key ) {
if ( !isset( $conf[$key] ) ) {
$this->baseLoadBalancerParams(),
[
'servers' => $this->makeServerArray( $template, $loads, $groupLoads ),
+ 'maxLag' => $this->maxLag,
'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
'readOnlyReason' => $readOnlyReason
]
/** @var string */
private $loadMonitorClass;
+ /** @var int */
+ private $maxLag;
+
+ /** @var int Default 'maxLag' when unspecified */
+ const MAX_LAG_DEFAULT = 10;
/**
* @see LBFactory::__construct()
$this->loadMonitorClass = isset( $conf['loadMonitorClass'] )
? $conf['loadMonitorClass']
: 'LoadMonitor';
+ $this->maxLag = isset( $conf['maxLag'] ) ? $conf['maxLag'] : self::MAX_LAG_DEFAULT;
}
/**
$this->baseLoadBalancerParams(),
[
'servers' => $servers,
+ 'maxLag' => $this->maxLag,
'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
]
) );
* - loadMonitor : Name of a class used to fetch server lag and load.
* - readOnlyReason : Reason the master DB is read-only if so [optional]
* - waitTimeout : Maximum time to wait for replicas for consistency [optional]
+ * - maxLag: Avoid replica DB servers with more lag than this [optional]
* - srvCache : BagOStuff object for server cache [optional]
* - wanCache : WANObjectCache object [optional]
* - chronologyProtector: ChronologyProtector object [optional]
private $disabled = false;
/** @var bool */
private $chronProtInitialized = false;
+ /** @var int */
+ private $maxLag = self::MAX_LAG_DEFAULT;
/** @var int Warn when this many connection are held */
const CONN_HELD_WARN_THRESHOLD = 10;
- /** @var int Default 'max lag' when unspecified */
+ /** @var int Default 'maxLag' when unspecified */
const MAX_LAG_DEFAULT = 10;
/** @var int Seconds to cache master server read-only status */
const TTL_CACHE_READONLY = 5;
$this->readOnlyReason = $params['readOnlyReason'];
}
+ if ( isset( $params['maxLag'] ) ) {
+ $this->maxLag = $params['maxLag'];
+ }
+
if ( isset( $params['loadMonitor'] ) ) {
$this->loadMonitorConfig = $params['loadMonitor'];
} else {
# How much lag this server nominally is allowed to have
$maxServerLag = isset( $this->mServers[$i]['max lag'] )
? $this->mServers[$i]['max lag']
- : self::MAX_LAG_DEFAULT; // default
+ : $this->maxLag; // default
# Constrain that futher by $maxLag argument
$maxServerLag = min( $maxServerLag, $maxLag );
$cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
$method = __METHOD__;
return $cache->getWithSetCallback(
- 'imagemagick-version',
+ $cache->makeGlobalKey( 'imagemagick-version' ),
$cache::TTL_HOUR,
function () use ( $method ) {
global $wgImageMagickConvertCommand;
*/
public static function anchorencode( $parser, $text ) {
$text = $parser->killMarkers( $text );
- return (string)substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
+ $section = (string)substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
+ return Sanitizer::safeEncodeAttribute( $section );
}
public static function special( $parser, $text ) {
'{' => '{',
'}' => '}', // prevent unpaired language conversion syntax
'[' => '[',
+ ']' => ']',
"''" => '''',
'ISBN' => 'ISBN',
'RFC' => 'RFC',
public function alterForm( HTMLForm $form ) {
$resetRoutes = $this->getConfig()->get( 'PasswordResetRoutes' );
+ $form->setSubmitDestructive();
+
$form->addHiddenFields( $this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
$i = 0;
/** @var bool|Title */
protected $rclTargetTitle;
+ protected $rclTarget;
+
function __construct() {
parent::__construct( 'Recentchangeslinked' );
}
public function parseParameters( $par, FormOptions $opts ) {
$opts['target'] = $par;
+ $this->rclTarget = $par;
}
/**
public function prefixSearchSubpages( $search, $limit, $offset ) {
return $this->prefixSearchString( $search, $limit, $offset );
}
+
+ /**
+ * Get a self-referential title object
+ * with consideration to the given subpage.
+ *
+ * @return Title
+ * @since 1.23
+ */
+ public function getPageTitle() {
+ return parent::getPageTitle( $this->rclTarget );
+ }
}
* @param HTMLForm $form
*/
protected function alterForm( HTMLForm $form ) {
+ $form->setSubmitDestructive();
if ( $this->getTokensList() ) {
$form->setSubmitTextMsg( 'resettokens-resetbutton' );
} else {
$out = $this->getOutput();
$out->setPageTitle( $this->msg( 'unblockip' ) );
- $out->addModules( [ 'mediawiki.special', 'mediawiki.userSuggest' ] );
+ $out->addModules( [ 'mediawiki.userSuggest' ] );
$form = HTMLForm::factory( 'ooui', $this->getFields(), $this->getContext() );
$form->setWrapperLegendMsg( 'unblockip' );
$this->setHeaders();
$this->outputHeader();
- $out->addModuleStyles( 'mediawiki.special.userrights.styles' );
+ $out->addModuleStyles( 'mediawiki.special' );
$this->addHelpLink( 'Help:Assigning permissions' );
$this->switchForm();
}
$ret .= "\t<td style='vertical-align:top;'>\n";
foreach ( $column as $group => $checkbox ) {
- $attr = $checkbox['disabled'] ? [ 'disabled' => 'disabled' ] : [];
+ $attr = [ 'class' => 'mw-userrights-groupcheckbox' ];
+ if ( $checkbox['disabled'] ) {
+ $attr['disabled'] = 'disabled';
+ }
$member = UserGroupMembership::getGroupMemberName( $group, $user->getName() );
if ( $checkbox['irreversible'] ) {
}
$checkboxHtml = Xml::checkLabel( $text, "wpGroup-" . $group,
"wpGroup-" . $group, $checkbox['set'], $attr );
- $ret .= "\t\t" . ( ( $checkbox['disabled'] && $checkbox['disabled-expiry'] )
- ? Xml::tags( 'div', [ 'class' => 'mw-userrights-disabled' ], $checkboxHtml )
- : Xml::tags( 'div', [], $checkboxHtml )
- ) . "\n";
if ( $this->canProcessExpiries() ) {
$uiUser = $this->getUser();
$expiryHtml .= $expiryFormOptions->getHTML() . '<br />';
// Add custom expiry field
- $attribs = [ 'id' => "mw-input-wpExpiry-$group-other" ];
+ $attribs = [
+ 'id' => "mw-input-wpExpiry-$group-other",
+ 'class' => 'mw-userrights-expiryfield',
+ ];
if ( $checkbox['disabled-expiry'] ) {
$attribs['disabled'] = 'disabled';
}
'id' => "mw-userrights-nested-wpGroup-$group",
'class' => 'mw-userrights-nested',
];
- $ret .= "\t\t\t" . Xml::tags( 'div', $divAttribs, $expiryHtml ) . "\n";
+ $checkboxHtml .= "\t\t\t" . Xml::tags( 'div', $divAttribs, $expiryHtml ) . "\n";
}
+ $ret .= "\t\t" . ( ( $checkbox['disabled'] && $checkbox['disabled-expiry'] )
+ ? Xml::tags( 'div', [ 'class' => 'mw-userrights-disabled' ], $checkboxHtml )
+ : Xml::tags( 'div', [], $checkboxHtml )
+ ) . "\n";
}
$ret .= "\t</td>\n";
}
*/
static public $languagesWithVariants = [
'en',
+ 'crh',
'gan',
'iu',
'kk',
--- /dev/null
+<?php
+/**
+ * Crimean Tatar (Qırımtatarca) specific code.
+ *
+ * Adapted from https://crh.wikipedia.org/wiki/Qullan%C4%B1c%C4%B1:Don_Alessandro/Translit
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Language
+ */
+
+/**
+ * Crimean Tatar (Qırımtatarca) converter routines
+ *
+ * @ingroup Language
+ */
+class CrhConverter extends LanguageConverter {
+ // Defines working character ranges
+ const WORD_BEGINS = '\r\s\"\'\(\)\-<>\[\]\/.,:;!?';
+ const WORD_ENDS = '\r\s\"\'\(\)\-<>\[\]\/.,:;!?';
+
+ // Cyrillic
+ const C_UC = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'; # Crimean Tatar Cyrillic uppercase
+ const C_LC = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'; # Crimean Tatar Cyrillic lowercase
+ const C_CONS_UC = 'БВГДЖЗЙКЛМНПРСТФХЦЧШЩCÑ'; # Crimean Tatar Cyrillic + CÑ uppercase consonants
+ const C_CONS_LC = 'бвгджзйклмнпрстфхцчшщcñ'; # Crimean Tatar Cyrillic + CÑ lowercase consonants
+ const C_M_CONS = 'бгкмпшcБГКМПШC'; # Crimean Tatar Cyrillic M-type consonants
+
+ # Crimean Tatar Cyrillic + CÑ consonants
+ const C_CONS = 'бвгджзйклмнпрстфхцчшщcñБВГДЖЗЙКЛМНПРСТФХЦЧШЩCÑ';
+
+ // Latin
+ const L_UC = 'AÂBCÇDEFGĞHIİJKLMNÑOÖPQRSŞTUÜVYZ'; # Crimean Tatar Latin uppercase
+ const L_LC = 'aâbcçdefgğhıijklmnñoöpqrsştuüvyz'; # Crimean Tatar Latin lowercase
+ const L_N_CONS_UC = 'ÇNRSTZ'; # Crimean Tatar Latin N-type upper case consonants
+ const L_N_CONS_LC = 'çnrstz'; # Crimean Tatar Latin N-type lower case consonants
+ const L_N_CONS = 'çnrstzÇNRSTZ'; # Crimean Tatar Latin N-type consonants
+ const L_M_CONS = 'bcgkmpşBCGKMPŞ'; # Crimean Tatar Latin M-type consonants
+ const L_CONS_UC = 'BCÇDFGHJKLMNÑPRSŞTVZ'; # Crimean Tatar Latin uppercase consonants
+ const L_CONS_LC = 'bcçdfghjklmnñprsştvz'; # Crimean Tatar Latin lowercase consonants
+ const L_CONS = 'bcçdfghjklmnñprsştvzBCÇDFGHJKLMNÑPRSŞTVZ'; # Crimean Tatar Latin consonants
+ const L_VOW_UC = 'AÂEIİOÖUÜ'; # Crimean Tatar Latin uppercase vowels
+ const L_VOW = 'aâeıioöuüAÂEIİOÖUÜ'; # Crimean Tatar Latin vowels
+ const L_F_UC = 'EİÖÜ'; # Crimean Tatar Latin uppercase front vowels
+ const L_F = 'eiöüEİÖÜ'; # Crimean Tatar Latin front vowels
+
+ public $mCyrillicToLatin = [
+
+ ## these are independent of location in the word, but have
+ ## to go first so other transforms don't bleed them
+ 'гъ' => 'ğ', 'Гъ' => 'Ğ', 'ГЪ' => 'Ğ',
+ 'къ' => 'q', 'Къ' => 'Q', 'КЪ' => 'Q',
+ 'нъ' => 'ñ', 'Нъ' => 'Ñ', 'НЪ' => 'Ñ',
+ 'дж' => 'c', 'Дж' => 'C', 'ДЖ' => 'C',
+
+ 'А' => 'A', 'а' => 'a', 'Б' => 'B', 'б' => 'b',
+ 'В' => 'V', 'в' => 'v', 'Г' => 'G', 'г' => 'g',
+ 'Д' => 'D', 'д' => 'd', 'Ж' => 'J', 'ж' => 'j',
+ 'З' => 'Z', 'з' => 'z', 'И' => 'İ', 'и' => 'i',
+ 'Й' => 'Y', 'й' => 'y', 'К' => 'K', 'к' => 'k',
+ 'Л' => 'L', 'л' => 'l', 'М' => 'M', 'м' => 'm',
+ 'Н' => 'N', 'н' => 'n', 'П' => 'P', 'п' => 'p',
+ 'Р' => 'R', 'р' => 'r', 'С' => 'S', 'с' => 's',
+ 'Т' => 'T', 'т' => 't', 'Ф' => 'F', 'ф' => 'f',
+ 'Х' => 'H', 'х' => 'h', 'Ч' => 'Ç', 'ч' => 'ç',
+ 'Ш' => 'Ş', 'ш' => 'ş', 'Ы' => 'I', 'ы' => 'ı',
+ 'Э' => 'E', 'э' => 'e', 'Е' => 'E', 'е' => 'e',
+ 'Я' => 'Â', 'я' => 'â', 'У' => 'U', 'у' => 'u',
+ 'О' => 'O', 'о' => 'o',
+
+ 'Ё' => 'Yo', 'ё' => 'yo', 'Ю' => 'Yu', 'ю' => 'yu',
+ 'Ц' => 'Ts', 'ц' => 'ts', 'Щ' => 'Şç', 'щ' => 'şç',
+ 'Ь' => '', 'ь' => '', 'Ъ' => '', 'ъ' => '',
+
+ ];
+
+ public $mLatinToCyrillic = [
+ 'Â' => 'Я', 'â' => 'я', 'B' => 'Б', 'b' => 'б',
+ 'Ç' => 'Ч', 'ç' => 'ч', 'D' => 'Д', 'd' => 'д',
+ 'F' => 'Ф', 'f' => 'ф', 'G' => 'Г', 'g' => 'г',
+ 'H' => 'Х', 'h' => 'х', 'I' => 'Ы', 'ı' => 'ы',
+ 'İ' => 'И', 'i' => 'и', 'J' => 'Ж', 'j' => 'ж',
+ 'K' => 'К', 'k' => 'к', 'L' => 'Л', 'l' => 'л',
+ 'M' => 'М', 'm' => 'м', 'N' => 'Н', 'n' => 'н',
+ 'O' => 'О', 'o' => 'о', 'P' => 'П', 'p' => 'п',
+ 'R' => 'Р', 'r' => 'р', 'S' => 'С', 's' => 'с',
+ 'Ş' => 'Ш', 'ş' => 'ш', 'T' => 'Т', 't' => 'т',
+ 'V' => 'В', 'v' => 'в', 'Z' => 'З', 'z' => 'з',
+
+ 'ya' => 'я', 'Ya' => 'Я', 'YA' => 'Я',
+ 'ye' => 'е', 'YE' => 'Е', 'Ye' => 'Е',
+
+ // hack, hack, hack
+ 'A' => 'А', 'a' => 'а', 'E' => 'Е', 'e' => 'е',
+ 'Ö' => 'О', 'ö' => 'о', 'U' => 'У', 'u' => 'у',
+ 'Ü' => 'У', 'ü' => 'у', 'Y' => 'Й', 'y' => 'й',
+
+ 'C' => 'Дж', 'c' => 'дж', 'Ğ' => 'Гъ', 'ğ' => 'гъ',
+ 'Ñ' => 'Нъ', 'ñ' => 'нъ', 'Q' => 'Къ', 'q' => 'къ',
+
+ ];
+
+ public $mExceptions = [];
+ public $mCyrl2LatnPatterns = [];
+ public $mLatn2CyrlPatterns = [];
+ public $mCyrlCleanUpRegexes = [];
+
+ public $mExceptionsLoaded = false;
+
+ function loadDefaultTables() {
+ $this->mTables = [
+ 'crh-latn' => new ReplacementArray( $this->mCyrillicToLatin ),
+ 'crh-cyrl' => new ReplacementArray( $this->mLatinToCyrillic ),
+ 'crh' => new ReplacementArray()
+ ];
+ }
+
+ function postLoadTables() {
+ $this->loadExceptions();
+ }
+
+ function loadExceptions() {
+ if ( $this->mExceptionsLoaded ) {
+ return;
+ }
+
+ $this->mExceptionsLoaded = true;
+ $crhExceptions = new MediaWiki\Languages\Data\CrhExceptions();
+ list( $this->mExceptions, $this->mCyrl2LatnPatterns, $this->mLatn2CyrlPatterns,
+ $this->mCyrlCleanUpRegexes ) = $crhExceptions->loadExceptions( self::L_LC . self::C_LC,
+ self::L_UC . self::C_UC );
+ }
+
+ /**
+ * A function wrapper:
+ * - if there is no selected variant, leave the link
+ * names as they were
+ * - do not try to find variants for usernames
+ *
+ * @param string &$link
+ * @param Title &$nt
+ * @param bool $ignoreOtherCond
+ */
+ function findVariantLink( &$link, &$nt, $ignoreOtherCond = false ) {
+ // check for user namespace
+ if ( is_object( $nt ) ) {
+ $ns = $nt->getNamespace();
+ if ( $ns == NS_USER || $ns == NS_USER_TALK ) {
+ return;
+ }
+ }
+
+ $oldlink = $link;
+ parent::findVariantLink( $link, $nt, $ignoreOtherCond );
+ if ( $this->getPreferredVariant() == $this->mMainLanguageCode ) {
+ $link = $oldlink;
+ }
+ }
+
+ /**
+ * It translates text into variant, specials:
+ * - ommiting roman numbers
+ *
+ * @param string $text
+ * @param bool $toVariant
+ *
+ * @throws MWException
+ * @return string
+ */
+ function translate( $text, $toVariant ) {
+ $letters = '';
+ switch ( $toVariant ) {
+ case 'crh-cyrl':
+ $letters = self::L_UC . self::L_LC . "\'";
+ break;
+ case 'crh-latn':
+ $letters = self::C_UC . self::C_LC . "";
+ break;
+ default:
+ return $text;
+ break;
+ }
+
+ if ( !$this->mTablesLoaded ) {
+ $this->loadTables();
+ }
+
+ if ( !isset( $this->mTables[$toVariant] ) ) {
+ throw new MWException( "Broken variant table: " . implode( ',', array_keys( $this->mTables ) ) );
+ }
+
+ // check for roman numbers like VII, XIX...
+ $roman = '/^M{0,3}(C[DM]|D{0,1}C{0,3})(X[LC]|L{0,1}X{0,3})(I[VX]|V{0,1}I{0,3})$/u';
+
+ # match any sub-string of the relevant letters and convert it
+ $matches = preg_split( '/(\b|^)[^' . $letters . ']+(\b|$)/u',
+ $text, -1, PREG_SPLIT_OFFSET_CAPTURE );
+ $mstart = 0;
+ $ret = '';
+ foreach ( $matches as $m ) {
+ # copy over the non-matching bit
+ $ret .= substr( $text, $mstart, $m[1] - $mstart );
+ # skip certain classes of strings
+
+ if ( array_key_exists( $m[0], $this->mExceptions ) ) {
+ # if it's an exception, just copy down the right answer
+ $ret .= $this->mExceptions[$m[0]];
+ } elseif ( ! $m[0] || # empty strings
+ preg_match( $roman, $m[0] ) || # roman numerals
+ preg_match( '/[^' . $letters . ']/', $m[0] ) # mixed orthography
+ ) {
+ $ret .= $m[0];
+ } else {
+ # convert according to the rules
+ $token = $this->regsConverter( $m[0], $toVariant );
+ $ret .= parent::translate( $token, $toVariant );
+ }
+ $mstart = $m[1] + strlen( $m[0] );
+ }
+
+ # pick up stray quote marks
+ switch ( $toVariant ) {
+ case 'crh-cyrl':
+ $ret = strtr( $ret, [ '“' => '«', '”' => '»', ] );
+ $ret = $this->regsConverter( $ret, 'cyrl-cleanup' );
+ break;
+ case 'crh-latn':
+ $ret = strtr( $ret, [ '«' => '"', '»' => '"', ] );
+ break;
+ }
+
+ return $ret;
+ }
+
+ private function regsConverter( $text, $toVariant ) {
+ if ( $text == '' ) return $text;
+
+ $pat = [];
+ $rep = [];
+ switch ( $toVariant ) {
+ case 'crh-latn':
+ foreach ( $this->mCyrl2LatnPatterns as $pat => $rep ) {
+ $text = preg_replace( $pat, $rep, $text );
+ }
+ return $text;
+ case 'crh-cyrl':
+ foreach ( $this->mLatn2CyrlPatterns as $pat => $rep ) {
+ $text = preg_replace( $pat, $rep, $text );
+ }
+ return $text;
+ case 'cyrl-cleanup':
+ foreach ( $this->mCyrlCleanUpRegexes as $pat => $rep ) {
+ $text = preg_replace( $pat, $rep, $text );
+ }
+ return $text;
+ default:
+ return $text;
+ }
+ }
+
+}
+
+/**
+ * Crimean Tatar (Qırımtatarca)
+ *
+ * @ingroup Language
+ */
+class LanguageCrh extends Language {
+
+ function __construct() {
+ parent::__construct();
+
+ $variants = [ 'crh', 'crh-cyrl', 'crh-latn' ];
+ $variantfallbacks = [
+ 'crh' => 'crh-latn',
+ 'crh-cyrl' => 'crh-latn',
+ 'crh-latn' => 'crh-cyrl',
+ ];
+
+ $this->mConverter = new CrhConverter( $this, 'crh', $variants, $variantfallbacks );
+ }
+}
--- /dev/null
+<?php
+/**
+ * Exceptions Tables for Crimean Tatar (crh / Qırımtatarca)
+ *
+ * Adapted from https://crh.wikipedia.org/wiki/Qullan%C4%B1c%C4%B1:Don_Alessandro/Translit
+ *
+ * @file
+ */
+
+namespace MediaWiki\Languages\Data;
+
+use \CrhConverter as Crh;
+
+class CrhExceptions {
+
+ function __construct() {
+ $this->loadRegs();
+ }
+
+ public $exceptionMap = [];
+ public $Cyrl2LatnPatterns = [];
+ public $Latn2CyrlPatterns = [];
+
+ private $lc2uc;
+ private $uc2lc;
+
+ private function initLcUc( $lcChars, $ucChars, $reinit = false ) {
+ # bail if we've already done this, unless we are re-initializing
+ if ( !$reinit && $this->lc2uc && $this->uc2lc ) {
+ return;
+ }
+
+ # split up the lc and uc lists in a unicode-friendly way
+ $myLc = [];
+ preg_match_all( '/./u', $lcChars, $myLc );
+ $myLc = $myLc[0];
+
+ $myUc = [];
+ preg_match_all( '/./u', $ucChars, $myUc );
+ $myUc = $myUc[0];
+
+ # map lc to uc and vice versa
+ $this->lc2uc = array_combine( array_values( $myLc ), array_values( $myUc ) );
+ $this->uc2lc = array_combine( array_values( $myUc ), array_values( $myLc ) );
+ }
+
+ private function myLc( $string ) {
+ return strtr( $string, $this->uc2lc );
+ }
+
+ private function myUc( $string ) {
+ return strtr( $string, $this->lc2uc );
+ }
+
+ private function myUcWord( $string ) {
+ return $this->myUc( mb_substr( $string, 0, 1 ) ) . $this->myLc( mb_substr( $string, 1 ) );
+ }
+
+ private function addMappings( $mapArray, &$A2B, &$B2A, $exactCase = false,
+ $prePat = '', $postPat = '' ) {
+ foreach ( $mapArray as $WordA => $WordB ) {
+ $ucA = $this->myUc( $WordA );
+ $ucWordA = $this->myUcWord( $WordA );
+ $ucB = $this->myUc( $WordB );
+ $ucWordB = $this->myUcWord( $WordB );
+
+ # if there are regexes, only map toward backregs
+ if ( ! preg_match( '/\$[1-9]/', $WordA ) ) {
+ $A2B[ $prePat . $WordA . $postPat ] = $WordB;
+ if ( ! $exactCase ) {
+ $A2B[ $prePat . $ucWordA . $postPat ] = $ucWordB;
+ $A2B[ $prePat . $ucA . $postPat ] = $ucB;
+ }
+ }
+
+ if ( ! preg_match( '/\$[1-9]/', $WordB ) ) {
+ $B2A[ $prePat . $WordB . $postPat ] = $WordA;
+ if ( ! $exactCase ) {
+ $B2A[ $prePat . $ucWordB . $postPat ] = $ucWordA;
+ $B2A[ $prePat . $ucB . $postPat ] = $ucA;
+ }
+ }
+ }
+ }
+
+ function loadExceptions( $lcChars, $ucChars ) {
+ # init lc and uc, as needed
+ $this->initLcUc( $lcChars, $ucChars );
+ # load C2L and L2C whole-word exceptions into the same array, since it's just a look up
+ # no regex prefix/suffix needed
+ $this->addMappings( $this->wordMappings, $this->exceptionMap, $this->exceptionMap );
+ $this->addMappings( $this->exactCaseMappings, $this->exceptionMap, $this->exceptionMap, true );
+
+ # load C2L and L2C bidirectional prefix mappings
+ $this->addMappings( $this->prefixMapping,
+ $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/^', '/u' );
+ $this->addMappings( $this->suffixMapping,
+ $this->Cyrl2LatnPatterns, $this->Latn2CyrlPatterns, false, '/', '$/u' );
+
+ # tack on one-way mappings to the ends of the prefix and suffix patterns
+ $this->Cyrl2LatnPatterns += $this->Cyrl2LatnRegexes;
+ $this->Latn2CyrlPatterns += $this->Latn2CyrlRegexes;
+
+ return [ $this->exceptionMap, $this->Cyrl2LatnPatterns,
+ $this->Latn2CyrlPatterns, $this->CyrlCleanUpRegexes ];
+ }
+
+ # map Cyrillic to Latin and back, whole word match only
+ # variants: all lowercase, all uppercase, first letter capitalized
+ # items with capture group refs (e.g., $1) are only mapped from the
+ # regex to the reference
+ private $wordMappings = [
+
+ #### originally Cyrillic to Latin
+ 'аджыумер' => 'acıümer', 'аджыусеин' => 'acıüsein', 'алейкум' => 'aleyküm',
+ 'бейуде' => 'beyüde', 'боливия' => 'boliviya', 'большевик' => 'bolşevik', 'борис' => 'boris',
+ 'борнен' => 'bornen', 'бугун' => 'bugün', 'бузкесен' => 'buzkesen', 'буксир' => 'buksir',
+ 'бульбуль' => 'bülbül', 'бульвар' => 'bulvar', 'бульдозер' => 'buldozer', 'бульон' => 'bulyon',
+ 'бунен' => 'bunen', 'буннен' => 'bunnen', 'бус-бутюн' => 'büs-bütün',
+ 'бутерброд' => 'buterbrod', 'буфер' => 'bufer', 'буфет' => 'bufet', 'гонъюл' => 'göñül',
+ 'горизонт' => 'gorizont', 'госпиталь' => 'gospital', 'гуливер' => 'guliver', 'гуна' => 'güna',
+ 'гунях' => 'günâh', 'гургуль' => 'gürgül', 'гуя' => 'güya', 'демирёл' => 'demiryol',
+ 'джуньджу' => 'cüncü', 'ёлнен' => 'yolnen', 'зумбуль' => 'zümbül', 'ильи' => 'ilyi', 'ишунь' =>
+ 'işün', 'кодекс' => 'kodeks', 'кодифик' => 'kodifik', 'койлю' => 'köylü', 'коккоз' =>
+ 'kökköz', 'коккозь' => 'kökköz', 'коккозю' => 'kökközü', 'кокос' => 'kokos',
+ 'коллег' => 'kolleg', 'коллект' => 'kollekt', 'коллекц' => 'kollekts', 'кольцов' => 'koltsov',
+ 'комбин' => 'kombin', 'комедия' => 'komediya', 'коменда' => 'komenda', 'комета' => 'kometa',
+ 'комис' => 'komis', 'комит' => 'komit', 'комите' => 'komite', 'коммент' => 'komment',
+ 'коммерс' => 'kommers', 'коммерц' => 'kommerts', 'компенс' => 'kompens', 'компил' => 'kompil',
+ 'компьютер' => 'kompyuter', 'конвейер' => 'konveyer', 'конвен' => 'konven',
+ 'конверт' => 'konvert', 'конденс' => 'kondens', 'кондитер' => 'konditer',
+ 'кондиц' => 'kondits', 'коник' => 'konik', 'консерв' => 'konserv', 'контейнер' => 'konteyner',
+ 'континент' => 'kontinent', 'конфе' => 'konfe', 'конфискац' => 'konfiskats',
+ 'концен' => 'kontsen', 'концерт' => 'kontsert', 'конъюктур' => 'konyuktur',
+ 'коньки' => 'konki', 'коньяк' => 'konyak', 'копирле' => 'kopirle', 'копия' => 'kopiya',
+ 'корбекул' => 'körbekül', 'кореиз' => 'koreiz', 'коренн' => 'korenn', 'корея' => 'koreya',
+ 'коридор' => 'koridor', 'корнеев' => 'korneyev', 'корре' => 'korre', 'корьбекул' =>
+ 'körbekül', 'косме' => 'kosme', 'космик' => 'kosmik', 'костюм' => 'kostüm', 'котельн' =>
+ 'koteln', 'котировка' => 'kotirovka', 'котлет' => 'kotlet', 'кочергин' => 'koçergin',
+ 'коше' => 'köşe', 'кудрин' => 'kudrin', 'кузнец' => 'kuznets', 'кулинар' => 'kulinar',
+ 'кулич' => 'kuliç', 'кульминац' => 'kulminats', 'культив' => 'kultiv',
+ 'культура' => 'kultura', 'куркулет' => 'kürkület', 'курсив' => 'kursiv', 'кушку' => 'küşkü',
+ 'куюк' => 'küyük', 'къарагоз' => 'qaragöz', 'къолязма' => 'qolyazma', 'къуртумер' =>
+ 'qurtümer', 'къуртусеин' => 'qurtüsein', 'марьино' => 'maryino', 'медьюн' => 'medyun',
+ 'месули' => 'mesüli', 'месуль' => 'mesül', 'мефкуре' => 'mefküre', 'могедек' => 'mögedek',
+ 'муур' => 'müür', 'муче' => 'müçe', 'муюз' => 'müyüz', 'огнево' => 'ognevo',
+ 'одеколон' => 'odekolon', 'одеса' => 'odesa', 'одесса' => 'odessa', 'озерки' => 'ozerki',
+ 'озерн' => 'ozern', 'озёрн' => 'ozörn', 'океан' => 'okean', 'оленев' => 'olenev',
+ 'олимп' => 'olimp', 'ольчер' => 'ölçer', 'онен' => 'onen', 'оннен' => 'onnen',
+ 'опера' => 'opera', 'оптим' => 'optim', 'опци' => 'optsi', 'опция' => 'optsiya',
+ 'орден' => 'orden', 'ордер' => 'order', 'ореанда' => 'oreanda', 'орех' => 'oreh',
+ 'оригинал' => 'original', 'ориент' => 'oriyent', 'оркестр' => 'orkestr', 'орлин' => 'orlin',
+ 'офис' => 'ofis', 'офицер' => 'ofitser', 'офсет' => 'ofset', 'оюннен' => 'oyunnen', 'побед' =>
+ 'pobed', 'полево' => 'polevo', 'поли' => 'poli', 'полюшко' => 'polüşko',
+ 'помидор' => 'pomidor', 'пониз' => 'poniz', 'порфир' => 'porfir', 'потелов' => 'potelov',
+ 'почетн' => 'poçetn', 'почётн' => 'poçötn', 'публик' => 'publik', 'публиц' => 'publits',
+ 'пушкин' => 'puşkin', 'сеитумер' => 'seitümer', 'сеитусеин' => 'seitüsein', 'сеитягъя' =>
+ 'seityağya', 'сеитягья' => 'seityagya', 'сеитяхья' => 'seityahya', 'сеитяя' => 'seityaya',
+ 'сейитумер' => 'seyitümer', 'сейитусеин' => 'seyitüsein', 'сейитягъя' => 'seyityağya',
+ 'сейитягья' => 'seyityagya', 'сейитяхья' => 'seyityahya', 'сейитяя' => 'seyityaya',
+ 'ультимат' => 'ultimat', 'ультра' => 'ultra', 'ульянов' => 'ulyanov', 'универ' => 'univer',
+ 'уника' => 'unika', 'унтер' => 'unter', 'урьян' => 'uryan', 'уткин' => 'utkin', 'учебн' =>
+ 'uçebn', 'шовини' => 'şovini', 'шоссе' => 'şosse', 'шубин' => 'şubin', 'шунен' => 'şunen',
+ 'шуннен' => 'şunnen', 'щёлкино' => 'şçolkino', 'эмирусеин' => 'emirüsein',
+ 'юзбашы' => 'yüzbaşı', 'юзйыл' => 'yüzyıl', 'юртер' => 'yurter', 'ющенко' => 'yuşçenko',
+
+ 'кою' => 'köyü', 'кок' => 'kök', 'ком-кок' => 'köm-kök', 'коп' => 'köp', 'ог' => 'ög',
+ 'юрип' => 'yürip', 'юз' => 'yüz', 'юк' => 'yük', 'буюп' => 'büyüp', 'буюк' => 'büyük',
+ 'джонк' => 'cönk', 'джонкю' => 'cönkü', 'устке' => 'üstke', 'устте' => 'üstte',
+ 'усттен' => 'üstten',
+
+ # шофёр needs to come after шофер to override it in the Latin-to-Cyrillic direction
+ 'шофер' => 'şoför',
+ 'шофёр' => 'şoför',
+
+ #### originally Latin to Cyrillic (deduped from above)
+
+ # слова на -аль
+ # words in -аль
+ 'актуаль' => 'aktual', 'диагональ' => 'diagonal', 'документаль' => 'dokumental',
+ 'эмсаль' => 'emsal', 'фааль' => 'faal', 'феодаль' => 'feodal', 'фестиваль' => 'festival',
+ 'горизонталь' => 'gorizontal', 'хроникаль' => 'hronikal', 'идеаль' => 'ideal',
+ 'инструменталь' => 'instrumental', 'икъмаль' => 'iqmal', 'икъбаль' => 'iqbal',
+ 'истикъбаль' => 'istiqbal', 'истикъляль' => 'istiqlâl', 'италия' => 'italiya',
+ 'италья' => 'italya', 'ишгъаль' => 'işğal', 'кафедраль' => 'kafedral', 'казуаль' => 'kazual',
+ 'коллегиаль' => 'kollegial', 'колоссаль' => 'kolossal', 'коммуналь' => 'kommunal',
+ 'кординаль' => 'kordinal', 'криминаль' => 'kriminal', 'легаль' => 'legal', 'леталь' => 'letal',
+ 'либераль' => 'liberal', 'локаль' => 'lokal', 'магистраль' => 'magistral',
+ 'материаль' => 'material', 'машиналь' => 'maşinal', 'меаль' => 'meal',
+ 'медальон' => 'medalyon', 'медаль' => 'medal', 'меридиональ' => 'meridional',
+ 'мешъаль' => 'meşal', 'минераль' => 'mineral', 'минималь' => 'minimal', 'мисаль' => 'misal',
+ 'модаль' => 'modal', 'музыкаль' => 'muzıkal', 'номиналь' => 'nominal', 'нормаль' => 'normal',
+ 'оптималь' => 'optimal', 'орбиталь' => 'orbital', 'оригиналь' => 'original',
+ 'педаль' => 'pedal', 'пропорциональ' => 'proportsional', 'профессиональ' => 'professional',
+ 'радикаль' => 'radikal', 'рациональ' => 'ratsional', 'реаль' => 'real',
+ 'региональ' => 'regional', 'суаль' => 'sual', 'шималь' => 'şimal',
+ 'территориаль' => 'territorial', 'тимсаль' => 'timsal', 'тоталь' => 'total',
+ 'уникаль' => 'unikal', 'универсаль' => 'universal', 'вертикаль' => 'vertikal',
+ 'виртуаль' => 'virtual', 'визуаль' => 'vizual', 'вуаль' => 'vual', 'зональ' => 'zonal',
+ 'зуаль' => 'zual',
+
+ # слова с мягким знаком перед а, о, у, э
+ # Words with a soft sign before а, о, у, э
+ 'бильакис' => 'bilakis', 'маальэсеф' => 'maalesef',
+ 'мельун' => 'melun', 'озьара' => 'özara', 'вельасыл' => 'velasıl',
+ 'ельаякъ' => 'yelayaq',
+ # these are ordered so C2L is correct (the later Latin one)
+ 'февкъульаде' => 'fevqülade','февкъульаде' => 'fevqulade',
+
+ # другие слова с мягким знаком
+ # Other words with a soft sign
+ 'альбатрос' => 'albatros', 'альбинос' => 'albinos', 'альбом' => 'albom',
+ 'альбумин' => 'albumin', 'алфавит' => 'alfavit', 'альфа' => 'alfa', 'альманах' => 'almanah',
+ 'альпинист' => 'alpinist', 'альтерн' => 'altern', 'альтру' => 'altru', 'альвеола' => 'alveola',
+ 'ансамбль' => 'ansambl', 'аньане' => 'anane', 'асфальт' => 'asfalt', 'бальнео' => 'balneo',
+ 'баарь' => 'baar', 'базальт' => 'bazalt', 'бинокль' => 'binokl', 'джурьат' => 'curat',
+ 'джурьат' => 'cürat', 'девальв' => 'devalv', 'факульт' => 'fakult', 'фальсиф' => 'falsif',
+ 'фольклор' => 'folklor', 'гальван' => 'galvan', 'геральд' => 'gerald', 'женьшень' => 'jenşen',
+ 'инвентарь' => 'inventar', 'кальк' => 'kalk', 'кальмар' => 'kalmar', 'консульт' => 'konsult',
+ 'контроль' => 'kontrol', 'кульмин' => 'kulmin', 'культур' => 'kultur', 'лагерь' => 'lager',
+ 'макъбуль' => 'maqbul', 'макъуль' => 'maqul', 'мальт' => 'malt', 'мальземе' => 'malzeme',
+ 'меджуль' => 'mecul', 'мешгуль' => 'meşgül', 'мешгъуль' => 'meşğul', 'мульти' => 'multi',
+ 'мусульман' => 'musulman', 'нефть' => 'neft', 'пальто' => 'palto', 'пароль' => 'parol',
+ 'патруль' => 'patrul', 'пенальти' => 'penalti', 'къальби' => 'qalbi', 'къальпке' => 'qalpke',
+ 'къальплер' => 'qalpler', 'къальпни' => 'qalpni', 'къальпте' => 'qalpte', 'къаарь' => 'qaar',
+ 'ресуль' => 'resul', 'рыцарь' => 'rıtsar', 'рояль' => 'royal', 'саарь' => 'saar',
+ 'спираль' => 'spiral', 'сульх' => 'sulh', 'сумбуль' => 'sumbul', 'суньий' => 'suniy',
+ 'темаюль' => 'temayul', 'шампунь' => 'şampun', 'вальс' => 'vals', 'вальц' => 'valts',
+ 'ведомость' => 'vedomost', 'зулькъарнейн' => 'zulqarneyn', 'январь' => 'yanvar',
+ 'февраль' => 'fevral', 'июнь' => 'iyün', 'сентябрь' => 'sentâbr', 'октябрь' => 'oktâbr',
+ 'ноябрь' => 'noyabr', 'декабрь' => 'dekabr',
+
+ # слова с твёрдым знаком
+ # Words with a solid sign
+ 'бидъат' => 'bidat', 'бузъюрек' => 'buzyürek', 'атешъюрек' => 'ateşyürek',
+ 'алъянакъ' => 'alyanaq', 'демиръёл' => 'demiryol', 'деръал' => 'deral', 'инъекц' => 'inyekts',
+ 'мефъум' => 'mefum', 'мешъум' => 'meşum', 'объект' => 'obyekt', 'разъезд' => 'razyezd',
+ 'субъект' => 'subyekt', 'хавъяр' => 'havyar', 'ямъям' => 'yamyam',
+
+ # слова с буквой щ
+ # words with щ
+ 'ящик' => 'yaşçik', 'мещан' => 'meşçan',
+
+ # слова с буквой ц
+ # words with ц
+ 'акциз' => 'aktsiz', 'ацет' => 'atset', 'блиц' => 'blits', 'бруцеллёз' => 'brutsellöz',
+ 'доцент' => 'dotsent', 'фармацевт' => 'farmatsevt', 'глицер' => 'glitser',
+ 'люцерна' => 'lütserna', 'лицей' => 'litsey', 'меццо' => 'metstso', 'наци' => 'natsi',
+ 'проце' => 'protse', 'рецеп' => 'retsep', 'реценз' => 'retsenz', 'теплица' => 'teplitsa',
+ 'вице' => 'vitse', 'цепс' => 'tseps', 'швейцар' => 'şveytsar',
+
+ # слова без буквы тс
+ # words with тс
+ 'агъартс' => 'ağarts', 'агъыртс' => 'ağırts', 'бильдиртс' => 'bildirts', 'битсин' => 'bitsin',
+ 'буюльтс' => 'büyülts', 'буютс' => 'büyüts', 'гебертс' => 'geberts', 'делиртс' => 'delirts',
+ 'эгрильтс' => 'egrilts', 'эксильтс' => 'eksilts', 'эшитс' => 'eşits', 'иритс' => 'irits',
+ 'иситс' => 'isits', 'ичиртс' => 'içirts', 'кертсин' => 'kertsin', 'кенишлетс' => 'kenişlets',
+ 'кийсетс' => 'kiysets', 'копюртс' => 'köpürts', 'косьтертс' => 'kösterts',
+ 'кучертс' => 'küçerts', 'кучюльтс' => 'küçülts', 'пертсин' => 'pertsin', 'къайтс' => 'qayts',
+ 'къутсуз' => 'qutsuz', 'орьтс' => 'örts', 'отьс' => 'öts', 'тартс' => 'tarts',
+ 'тутсун' => 'tutsun', 'тюнъюльтс' => 'tüñülts', 'тюртс' => 'türts', 'янъартс' => 'yañarts',
+ 'ебертс' => 'yeberts', 'етсин' => 'yetsin', 'ешертс' => 'yeşerts', 'йиритс' => 'yirits',
+
+ # разные исключения
+ # different exceptions
+ 'бейуде' => 'beyude', 'бугунь' => 'bugün', 'бюджет' => 'bücet', 'бюллет' => 'büllet',
+ 'бюро' => 'büro', 'бюст' => 'büst', 'джонк' => 'cönk', 'диалог' => 'dialog',
+ 'гонъюль' => 'göñül', 'ханымэфенди' => 'hanımefendi', 'каньон' => 'kanyon', 'кирил' => 'kiril',
+ 'кирил' => 'kirill', 'кёрджа' => 'körca', 'кой' => 'köy', 'кулеръюзь' => 'küleryüz',
+ 'маалле' => 'маальle', 'майор' => 'mayor', 'маниал' => 'manиаль', 'мефкуре' => 'mefküre',
+ 'месуль' => 'mesul', 'месуль' => 'mesül', 'муурь' => 'müür',
+ 'нормала' => 'нормальa', 'нумюне' => 'nümüne', 'проект' => 'proekt', 'район' => 'rayon',
+ 'сойады' => 'soyadı', 'спортсмен' => 'sportsmen', 'услюп' => 'üslüp', 'услюб' => 'üslüb',
+ 'вакъиал' => 'vaqиаль', 'юзйыллыкъ' => 'yüzyıllıq',
+
+ # имена собственные
+ # proper names
+ 'адольф' => 'adolf', 'альберт' => 'albert', 'бешуй' => 'beşüy', 'эмирусеин' => 'emirüsein',
+ 'флотск' => 'flotsk', 'гайана' => 'gayana', 'грэсовский' => 'gresovskiy', 'гриц' => 'grits',
+ 'гурджи' => 'gürci', 'игорь' => 'igor', 'ильич' => 'ilyiç', 'ильин' => 'ilyin',
+ 'исмаил' => 'ismail', 'киттс' => 'kitts', 'комсомольск' => 'komsomolsk',
+ 'корьбекулю' => 'körbekülü', 'корьбекуль' => 'körbekül', 'куницын' => 'kunitsın',
+ 'львив' => 'lviv', 'львов' => 'lvov', 'марьино' => 'maryino', 'махульдюр' => 'mahuldür',
+ 'павел' => 'pavel', 'пантикапейон' => 'pantikapeyon', 'къарагозь' => 'qaragöz',
+ 'къуртсейит' => 'qurtseyit', 'къуртсеит' => 'qurtseit', 'къуртумер' => 'qurtümer',
+ 'сейитумер' => 'seyitümer', 'сеитумер' => 'seitümer', 'смаил' => 'smail',
+ 'советск' => 'sovetsk', 'шемьи-заде' => 'şemi-zade', 'щёлкино' => 'şçolkino',
+ 'тсвана' => 'tsvana', 'учьэвли' => 'üçevli', 'йохан' => 'yohan', 'йорк' => 'york',
+ 'ющенко' => 'yuşçenko', 'льная' => 'lnaya', 'льное' => 'lnoye', 'льный' => 'lnıy',
+ 'льская' => 'lskaya', 'льский' => 'lskiy', 'льское' => 'lskoye', 'ополь' => 'opol',
+
+ # originally Latin to Cyrillic, deduped from above
+ 'ань' => 'an', 'аньге' => 'ange', 'аньде' => 'ande', 'аньки' => 'anki', 'кёр' => 'kör',
+ 'мэр' => 'mer', 'этсин' => 'etsin',
+
+ # exceptions added after speaker review
+ # see https://www.mediawiki.org/wiki/User:TJones_(WMF)/T23582
+ 'аджизленювинъиз' => 'acizlenüviñiz', 'акъшам' => 'aqşam', 'алчакъгонъюлли' => 'alçaqgöñülli',
+ 'аньанелер' => 'ananeler', 'аньанелеримиз' => 'ananelerimiz',
+ 'аньанелеримизден' => 'ananelerimizden', 'аньанелеримизни' => 'ananelerimizni',
+ 'аньанели' => 'ananeli', 'асфальтке' => 'asfaltke', 'баарьде' => 'baarde', 'бахтсыз' => 'bahtsız',
+ 'берилюви' => 'berilüvi', 'берювден' => 'berüvden', 'берювни' => 'berüvni',
+ 'большевиклер' => 'bolşevikler', 'большевиклерге' => 'bolşeviklerge', 'болюк' => 'bölük',
+ 'болюнген' => 'bölüngen', 'болюнгенини' => 'bölüngenini', 'болюшип' => 'bölüşip',
+ 'бугуннинъ' => 'bugünniñ', 'бугуньден' => 'bugünden', 'бугуньки' => 'bugünki',
+ 'букюльген' => 'bükülgen', 'букюльди' => 'büküldi', 'буллюр' => 'büllür',
+ 'бурюмчик' => 'bürümçik', 'бурюнген' => 'bürüngen', 'бутюн' => 'bütün', 'бутюнлей' => 'bütünley',
+ 'буюген' => 'büyügen', 'буюй' => 'büyüy', 'волость' => 'volost', 'волостьларгъа' => 'volostlarğa',
+ 'гонъюлини' => 'göñülini', 'гонъюлли' => 'göñülli', 'гонъюллилер' => 'göñülliler',
+ 'госпиталинде' => 'gospitalinde', 'госпитальге' => 'gospitalge', 'госпитальде' => 'gospitalde',
+ 'гренадёр' => 'grenadör', 'гугюм' => 'gügüm', 'гугюмлер' => 'gügümler',
+ 'гугюмлери' => 'gügümleri', 'гугюмлерини' => 'gügümlerini', 'гурьсюльди' => 'gürsüldi',
+ 'гурюльдештилер' => 'gürüldeştiler', 'гурюльти' => 'gürülti', 'гурюльтили' => 'gürültili',
+ 'гурюльтисидир' => 'gürültisidir', 'дарульмуаллиминде' => 'darülmualliminde',
+ 'дарульмуаллимининде' => 'darülmuallimininde', 'дарульмуаллиминнинъ' => 'darülmualliminniñ',
+ 'дёгюльген' => 'dögülgen', 'декабрьде' => 'dekabrde', 'дёндюрилип' => 'döndürilip',
+ 'дёнермиз' => 'dönermiz', 'дёнмектелер' => 'dönmekteler', 'денъишюв' => 'deñişüv',
+ 'дёрдю' => 'dördü', 'дёрдюмиз' => 'dördümiz', 'дёрдюнджи' => 'dördünci', 'дёрт' => 'dört',
+ 'дертлешювге' => 'dertleşüvge', 'джесюр' => 'cesür', 'джесюране' => 'cesürane',
+ 'джесюрликлерини' => 'cesürliklerini', 'джонегенлерини' => 'cönegenlerini',
+ 'джонедим' => 'cönedim', 'джонейлер' => 'cöneyler', 'джурьатсызлыгъына' => 'cüratsızlığına',
+ 'дюгюнлер' => 'dügünler', 'дюгюнлерле' => 'dügünlerle', 'дюдюк' => 'düdük', 'дюльбер' => 'dülber',
+ 'дюльбери' => 'dülberi', 'дюльберлер' => 'dülberler', 'дюльберлернинъ' => 'dülberlerniñ',
+ 'дюльгер' => 'dülger', 'дюльгерге' => 'dülgerge', 'дюльгерлернинъки' => 'dülgerlerniñki',
+ 'дюльгерни' => 'dülgerni', 'дюльгернинъ' => 'dülgerniñ', 'дюмбюрдетти' => 'dümbürdetti',
+ 'дюмен' => 'dümen', 'дюмени' => 'dümeni', 'дюнья' => 'dünya', 'дюньявий' => 'dünyaviy',
+ 'дюньяда' => 'dünyada', 'дюньяларгъа' => 'dünyalarğa', 'дюньяларда' => 'dünyalarda',
+ 'дюньяны' => 'dünyanı', 'дюньянынъ' => 'dünyanıñ', 'дюньясы' => 'dünyası',
+ 'ельаякълылар' => 'yelayaqlılar', 'елькъуваны' => 'yelquvanı', 'ильич' => 'i̇liç',
+ 'ичюн' => 'içün', 'ичюнми' => 'içünmi', 'келюви' => 'kelüvi', 'келювини' => 'kelüvini',
+ 'келювинъизде' => 'kelüviñizde', 'келювни' => 'kelüvni', 'кемирювлер' => 'kemirüvler',
+ 'кесювде' => 'kesüvde', 'кетюв' => 'ketüv', 'кетювге' => 'ketüvge', 'кетюви' => 'ketüvi',
+ 'кетювимни' => 'ketüvimni', 'кетювлер' => 'ketüvler', 'кетювлери' => 'ketüvleri',
+ 'кетювлеринънинъ' => 'ketüvleriñniñ', 'кетювнинъ' => 'ketüvniñ', 'кирюв' => 'kirüv',
+ 'князь' => 'knâz', 'козькъапакъларыны' => 'közqapaqlarını', 'козьлю' => 'közlü', 'козю' => 'közü',
+ 'козюме' => 'közüme', 'козюнде' => 'közünde', 'козюне' => 'közüne', 'козюнен' => 'közünen',
+ 'козюнинъ' => 'közüniñ', 'козюнъни' => 'közüñni', 'койлюде' => 'köylüde',
+ 'койлюлер' => 'köylüler', 'койлюлерде' => 'köylülerde', 'койлюлерни' => 'köylülerni',
+ 'койлюлернинъ' => 'köylülerniñ', 'койлюнинъ' => 'köylüniñ', 'коккозьге' => 'kökközge',
+ 'коккозьде' => 'kökközde', 'коккозьдеки' => 'kökközdeki', 'коккозьден' => 'kökközden',
+ 'кокюс' => 'köküs', 'кокюси' => 'köküsi', 'кокюсим' => 'köküsim', 'кокюсиме' => 'köküsime',
+ 'кокюсинъе' => 'köküsiñe', 'комиссарлар' => 'komissarlar', 'комиссарлары' => 'komissarları',
+ 'комитетининъ' => 'komitetiniñ', 'концлагерь' => 'kontslager', 'копьмеди' => 'köpmedi',
+ 'копьти' => 'köpti', 'копюр' => 'köpür', 'копюрге' => 'köpürge', 'копюрден' => 'köpürden',
+ 'копюри' => 'köpüri', 'копюрнинъ' => 'köpürniñ', 'коридорда' => 'koridorda',
+ 'корьсюн' => 'körsün', 'корюв' => 'körüv', 'корюльген' => 'körülgen', 'корюнди' => 'köründi',
+ 'корюндинъ' => 'köründiñ', 'корюне' => 'körüne', 'корюнип' => 'körünip',
+ 'корюнмеген' => 'körünmegen', 'корюнмеди' => 'körünmedi', 'корюнмедилер' => 'körünmediler',
+ 'корюнмей' => 'körünmey', 'корюнмейсинъиз' => 'körünmeysiñiz', 'корюнмекте' => 'körünmekte',
+ 'корюнмектелер' => 'körünmekteler', 'корюнъиз' => 'körüñiz', 'корюше' => 'körüşe',
+ 'корюшеджекмиз' => 'körüşecekmiz', 'корюшим' => 'körüşim', 'корюшип' => 'körüşip',
+ 'корюширмиз' => 'körüşirmiz', 'корюшкен' => 'körüşken', 'корюшкенде' => 'körüşkende',
+ 'корюшмеге' => 'körüşmege', 'корюшмегенимиз' => 'körüşmegenimiz', 'корюштик' => 'körüştik',
+ 'корюштим' => 'körüştim', 'корюшюв' => 'körüşüv', 'корюшювде' => 'körüşüvde',
+ 'корюшювден' => 'körüşüvden', 'корюшюви' => 'körüşüvi', 'корюшювимден' => 'körüşüvimden',
+ 'корюшювимизге' => 'körüşüvimizge', 'корюшювимизден' => 'körüşüvimizden',
+ 'костюми' => 'kostümi', 'кузю' => 'küzü', 'кулькюден' => 'külküden', 'кулькюнинъ' => 'külküniñ',
+ 'кулькюсининъ' => 'külküsiniñ', 'кулю' => 'külü', 'кулюмсиреген' => 'külümsiregen',
+ 'кулюмсиреди' => 'külümsiredi', 'кулюмсиредим' => 'külümsiredim', 'кулюмсирей' => 'külümsirey',
+ 'кулюмсирейим' => 'külümsireyim', 'кулюмсиреп' => 'külümsirep', 'кулюни' => 'külüni',
+ 'кулюнчли' => 'külünçli', 'кулюшинде' => 'külüşinde', 'кулюштилер' => 'külüştiler',
+ 'кумюш' => 'kümüş', 'куньдюз' => 'kündüz', 'куньдюзлери' => 'kündüzleri', 'куньлюк' => 'künlük',
+ 'куню' => 'künü', 'кунюмде' => 'künümde', 'кунюнде' => 'kününde', 'кунюндеми' => 'künündemi',
+ 'кунюнъ' => 'künüñ', 'курькчю' => 'kürkçü', 'курьсю' => 'kürsü', 'курьсюге' => 'kürsüge',
+ 'курьсюлер' => 'kürsüler', 'курючтен' => 'kürüçten', 'кутюклерни' => 'kütüklerni',
+ 'кутюкли' => 'kütükli', 'кучьлю' => 'küçlü', 'кучьлюклер' => 'küçlükler',
+ 'кучьсюнмезсинъ' => 'küçsünmezsiñ', 'кучюджик' => 'küçücik', 'кучюк' => 'küçük',
+ 'кучюм' => 'küçüm', 'кучюмле' => 'küçümle', 'кучюнден' => 'küçünden', 'кучюни' => 'küçüni',
+ 'къаарьлене' => 'qaarlene', 'къаарьли' => 'qaarli', 'къальбим' => 'qalbim',
+ 'къальбимни' => 'qalbimni', 'къальбинде' => 'qalbinde', 'къальпли' => 'qalpli',
+ 'къальптен' => 'qalpten', 'къалюбелядан' => 'qalübelâdan', 'къулюбенъде' => 'qulübeñde',
+ 'лёман' => 'löman', 'львованынъ' => 'lvovanıñ', 'лютфи' => 'lütfi', 'лютфиге' => 'lütfige',
+ 'лютфини' => 'lütfini', 'мазюн' => 'mazün', 'малюм' => 'malüm', 'малюмат' => 'malümat',
+ 'махлюкъаттан' => 'mahlüqattan', 'махлюкътан' => 'mahlüqtan', 'махульдюрге' => 'mahuldürge',
+ 'махульдюрде' => 'mahuldürde', 'махульдюрдеки' => 'mahuldürdeki',
+ 'махульдюрден' => 'mahuldürden', 'махульдюрли' => 'mahuldürli',
+ 'махульдюрлилер' => 'mahuldürliler', 'махульдюрлилермиз' => 'mahuldürlilermiz',
+ 'махульдюрми' => 'mahuldürmi', 'махульдюрни' => 'mahuldürni', 'мевджут' => 'mevcut',
+ 'мезкюр' => 'mezkür', 'мектюп' => 'mektüp', 'мектюпни' => 'mektüpni', 'мектюпте' => 'mektüpte',
+ 'мелитопольге' => 'melitopolge', 'мемнюн' => 'memnün', 'мемнюниетле' => 'memnüniyetle',
+ 'мемнюним' => 'memnünim', 'мемнюнмиз' => 'memnünmiz', 'менсюп' => 'mensüp',
+ 'мешгъульмиз' => 'meşğulmiz', 'мулькюни' => 'mülküni', 'мумкюн' => 'mümkün',
+ 'мумкюнми' => 'mümkünmi', 'мусульманлар' => 'musulmanlar', 'мусульманлармы' => 'musulmanlarmı',
+ 'мухкемлендирюв' => 'mühkemlendirüv', 'мушкюль' => 'müşkül', 'ничюн' => 'niçün',
+ 'ничюндир' => 'niçündir', 'нумюнеси' => 'nümünesi', 'огю' => 'ögü', 'огюз' => 'ögüz',
+ 'огюмде' => 'ögümde', 'огюмдеки' => 'ögümdeki', 'огюме' => 'ögüme', 'огюмизге' => 'ögümizge',
+ 'огюмизде' => 'ögümizde', 'огюмиздеки' => 'ögümizdeki', 'огюмни' => 'ögümni',
+ 'огюнде' => 'ögünde', 'огюндеки' => 'ögündeki', 'огюндекиси' => 'ögündekisi',
+ 'огюнден' => 'ögünden', 'огюне' => 'ögüne', 'огюнъизде' => 'ögüñizde', 'огютини' => 'ögütini',
+ 'огютлерини' => 'ögütlerini', 'озю' => 'özü', 'озюм' => 'özüm', 'озюмден' => 'özümden',
+ 'озюме' => 'özüme', 'озюмизни' => 'özümizni', 'озюмизнинъ' => 'özümizniñ',
+ 'озюмизнинъки' => 'özümizniñki', 'озюмнен' => 'özümnen', 'озюмни' => 'özümni',
+ 'озюмнинъ' => 'özümniñ', 'озюнде' => 'özünde', 'озюнден' => 'özünden', 'озюне' => 'özüne',
+ 'озюнен' => 'özünen', 'озюни' => 'özüni', 'озюнинъ' => 'özüniñ', 'озюнинъкими' => 'özüniñkimi',
+ 'озюнъ' => 'özüñ', 'озюнъе' => 'özüñe', 'озюнъиз' => 'özüñiz', 'озюнъиздеки' => 'özüñizdeki',
+ 'озюнъни' => 'özüñni', 'оксюз' => 'öksüz', 'окюндим' => 'ökündim', 'ольдюрип' => 'öldürip',
+ 'ольдюрмек' => 'öldürmek', 'ольдюрювде' => 'öldürüvde', 'ольчюде' => 'ölçüde', 'олюм' => 'ölüm',
+ 'олюмден' => 'ölümden', 'олюмлер' => 'ölümler', 'омюр' => 'ömür', 'омюрге' => 'ömürge',
+ 'омюри' => 'ömüri', 'опькеленюв' => 'öpkelenüv', 'орьтилюви' => 'örtilüvi', 'орьтюли' => 'örtüli',
+ 'орюли' => 'örüli', 'орюлип' => 'örülip', 'осюв' => 'ösüv', 'осюмлик' => 'ösümlik',
+ 'отькерювни' => 'ötkerüvni', 'отькюр' => 'ötkür', 'офицери' => 'ofitseri',
+ 'офицерим' => 'ofitserim', 'офицерлер' => 'ofitserler', 'пальтосыны' => 'paltosını',
+ 'пальтосынынъ' => 'paltosınıñ', 'пекинюв' => 'pekinüv', 'пекитювнинъ' => 'pekitüvniñ',
+ 'пиширюв' => 'pişirüv', 'повидло' => 'povidlo', 'полис' => 'polis', 'полициясы' => 'politsiyası',
+ 'помещик' => 'pomeşçik', 'потюк' => 'potük', 'потюклеринен' => 'potüklerinen',
+ 'пулемёт' => 'pülemöt', 'пулемётларны' => 'pülemötlarnı', 'режиссёр' => 'rejissör',
+ 'ролюнде' => 'rolünde', 'севастопольнинъ' => 'sevastopolniñ', 'сёгди' => 'sögdi', 'сёз' => 'söz',
+ 'сёзлер' => 'sözler', 'сёзлери' => 'sözleri', 'сёзлерим' => 'sözlerim',
+ 'сёзлеримден' => 'sözlerimden', 'сёзлериме' => 'sözlerime', 'сёзлеримни' => 'sözlerimni',
+ 'сёзлеримнинъ' => 'sözlerimniñ', 'сёзлеринде' => 'sözlerinde', 'сёзлерине' => 'sözlerine',
+ 'сёзлерини' => 'sözlerini', 'сёзлерининъ' => 'sözleriniñ', 'сёзлеринъиз' => 'sözleriñiz',
+ 'сёзлеринъизни' => 'sözleriñizni', 'сёзлернен' => 'sözlernen', 'сёзлерни' => 'sözlerni',
+ 'сёзлернинъ' => 'sözlerniñ', 'сёзнен' => 'söznen', 'сёзни' => 'sözni', 'сёзчиклер' => 'sözçikler',
+ 'сёзчиклерден' => 'sözçiklerden', 'сёзю' => 'sözü', 'сёзюмен' => 'sözümen',
+ 'сёзюмнинъ' => 'sözümniñ', 'сёзюне' => 'sözüne', 'сёзюни' => 'sözüni', 'сёзюнинъ' => 'sözüniñ',
+ 'сёйле' => 'söyle', 'сёйлегенде' => 'söylegende', 'сёйлегенлеринден' => 'söylegenlerinden',
+ 'сёйледи' => 'söyledi', 'сёйлей' => 'söyley', 'сёйленди' => 'söylendi',
+ 'сёйленмеге' => 'söylenmege', 'сёйленмекте' => 'söylenmekte', 'сёйленъиз' => 'söyleñiz',
+ 'сёнген' => 'söngen', 'сёнди' => 'söndi', 'сёндюрди' => 'söndürdi',
+ 'сёндюрильген' => 'söndürilgen', 'сёндюрип' => 'söndürip', 'сентябрьнинъ' => 'sentâbrniñ',
+ 'сергюзешт' => 'sergüzeşt', 'сергюзештлерни' => 'sergüzeştlerni',
+ 'ставропольге' => 'stavropolge', 'сулькевич' => 'sulkeviç', 'сурьат' => 'surat',
+ 'суфлёр' => 'suflör', 'сюеги' => 'süyegi', 'сюеклерге' => 'süyeklerge',
+ 'сюйрекледи' => 'süyrekledi', 'сюйреле' => 'süyrele', 'сюйрен' => 'süyren',
+ 'сюйренге' => 'süyrenge', 'сюйренде' => 'süyrende', 'сюйреп' => 'süyrep', 'сюйрю' => 'süyrü',
+ 'сюкюнет' => 'sükünet', 'сюкюнети' => 'süküneti', 'сюкюнетте' => 'sükünette', 'сюкют' => 'süküt',
+ 'сюляле' => 'sülâle', 'сюрген' => 'sürgen', 'сюрди' => 'sürdi', 'сюрмеди' => 'sürmedi',
+ 'сюрюльмеген' => 'sürülmegen', 'сют' => 'süt', 'тебессюм' => 'tebessüm', 'тёкип' => 'tökip',
+ 'тёкти' => 'tökti', 'тёкюльген' => 'tökülgen', 'тёкюльди' => 'töküldi',
+ 'тёкюндиси' => 'tökündisi', 'тёле' => 'töle', 'тёледим' => 'töledim', 'телюке' => 'telüke',
+ 'телюкели' => 'telükeli', 'тенеффюс' => 'teneffüs', 'тенеффюслер' => 'teneffüsler',
+ 'тёпеге' => 'töpege', 'тёпелери' => 'töpeleri', 'тёпелерине' => 'töpelerine',
+ 'тёпели' => 'töpeli', 'тёпеси' => 'töpesi', 'тёпесинден' => 'töpesinden',
+ 'тёпесини' => 'töpesini', 'тёрге' => 'törge', 'тёрде' => 'törde', 'тёрдеки' => 'tördeki',
+ 'тёрюне' => 'törüne', 'тешеббюсим' => 'teşebbüsim', 'тёшегинден' => 'töşeginden',
+ 'тёшегине' => 'töşegine', 'тёшек' => 'töşek', 'тешеккюр' => 'teşekkür',
+ 'тешеккюрлер' => 'teşekkürler', 'тёшекни' => 'töşekni', 'тёшектен' => 'töşekten',
+ 'тёшели' => 'töşeli', 'тёшемек' => 'töşemek', 'тёшеп' => 'töşep', 'теэссюф' => 'teessüf',
+ 'тюбю' => 'tübü', 'тюбюнде' => 'tübünde', 'тюбюндеки' => 'tübündeki', 'тюз' => 'tüz',
+ 'тюзельгенге' => 'tüzelgenge', 'тюзельтмек' => 'tüzeltmek', 'тюземликлер' => 'tüzemlikler',
+ 'тюзетип' => 'tüzetip', 'тюзетирим' => 'tüzetirim', 'тюзеткен' => 'tüzetken',
+ 'тюзетмеге' => 'tüzetmege', 'тюзетмесенъ' => 'tüzetmeseñ', 'тюзетти' => 'tüzetti',
+ 'тюзетюв' => 'tüzetüv', 'тюкенмез' => 'tükenmez', 'тюкюриктен' => 'tükürikten',
+ 'тюкян' => 'tükân', 'тюкяны' => 'tükânı', 'тюкянында' => 'tükânında', 'тюм' => 'tüm',
+ 'тюневин' => 'tünevin', 'тюневинки' => 'tünevinki', 'тюпсюз' => 'tüpsüz', 'тюрк' => 'türk',
+ 'тюрклернинъ' => 'türklerniñ', 'тюркнинъ' => 'türkniñ', 'тюркче' => 'türkçe', 'тюркю' => 'türkü',
+ 'тюркюлерини' => 'türkülerini', 'тюркюнинъ' => 'türküniñ', 'тюрлю' => 'türlü',
+ 'тюртип' => 'türtip', 'тюрттинъиз' => 'türttiñiz', 'тютемекте' => 'tütemekte', 'тютюн' => 'tütün',
+ 'тютюнджи' => 'tütünci', 'тюфеги' => 'tüfegi', 'тюфегини' => 'tüfegini', 'тюфек' => 'tüfek',
+ 'тюфеклеринен' => 'tüfeklerinen', 'тюфеклернен' => 'tüfeklernen', 'тюфеклерни' => 'tüfeklerni',
+ 'тюфекнен' => 'tüfeknen', 'тюфексиз' => 'tüfeksiz', 'тюш' => 'tüş', 'тюше' => 'tüşe',
+ 'тюшеджек' => 'tüşecek', 'тюшеджексинъми' => 'tüşeceksiñmi', 'тюшем' => 'tüşem',
+ 'тюшип' => 'tüşip', 'тюшкен' => 'tüşken', 'тюшкенде' => 'tüşkende', 'тюшкенлер' => 'tüşkenler',
+ 'тюшмеге' => 'tüşmege', 'тюшмейим' => 'tüşmeyim', 'тюшмейлер' => 'tüşmeyler',
+ 'тюшмек' => 'tüşmek', 'тюшмекте' => 'tüşmekte', 'тюшмеси' => 'tüşmesi', 'тюшсе' => 'tüşse',
+ 'тюшти' => 'tüşti', 'тюштик' => 'tüştik', 'тюштилер' => 'tüştiler', 'тюштими' => 'tüştimi',
+ 'тюштинъиз' => 'tüştiñiz', 'тюшювден' => 'tüşüvden', 'тюшюджек' => 'tüşücek',
+ 'тюшюнген' => 'tüşüngen', 'тюшюнгендже' => 'tüşüngence', 'тюшюндже' => 'tüşünce',
+ 'тюшюнджеге' => 'tüşüncege', 'тюшюнджелер' => 'tüşünceler', 'тюшюнджелери' => 'tüşünceleri',
+ 'тюшюнджелерим' => 'tüşüncelerim', 'тюшюнджели' => 'tüşünceli', 'тюшюнджеси' => 'tüşüncesi',
+ 'тюшюнди' => 'tüşündi', 'тюшюндим' => 'tüşündim', 'тюшюне' => 'tüşüne',
+ 'тюшюнелер' => 'tüşüneler', 'тюшюнесинъиз' => 'tüşünesiñiz', 'тюшюнип' => 'tüşünip',
+ 'тюшюнмеге' => 'tüşünmege', 'тюшюнмезсинъ' => 'tüşünmezsiñ', 'тюшюнмей' => 'tüşünmey',
+ 'тюшюнмемек' => 'tüşünmemek', 'тюшюргенлер' => 'tüşürgenler', 'тюшюрди' => 'tüşürdi',
+ 'тюшюрдик' => 'tüşürdik', 'тюшюре' => 'tüşüre', 'тюшюрип' => 'tüşürip', 'тюшюрмек' => 'tüşürmek',
+ 'уджюм' => 'ücüm', 'удюр' => 'üdür', 'узюле' => 'üzüle', 'узюлип' => 'üzülip',
+ 'узюльгенини' => 'üzülgenini', 'узюльди' => 'üzüldi', 'уйрюлип' => 'üyrülip',
+ 'укюмет' => 'ükümet', 'укюмети' => 'ükümeti', 'укюметими' => 'ükümetimi',
+ 'укюметимиз' => 'ükümetimiz', 'укюметини' => 'ükümetini', 'укюметининъ' => 'ükümetiniñ',
+ 'укюметке' => 'ükümetke', 'укюметкеми' => 'ükümetkemi', 'укюметми' => 'ükümetmi',
+ 'укюметнинъ' => 'ükümetniñ', 'укюметтен' => 'ükümetten', 'укюмран' => 'ükümran',
+ 'улькюн' => 'ülkün', 'умюдим' => 'ümüdim', 'умют' => 'ümüt', 'умютлери' => 'ümütleri',
+ 'умютсизден' => 'ümütsizden', 'усть' => 'üst', 'устьке' => 'üstke', 'устьлеринде' => 'üstlerinde',
+ 'устьлериндеки' => 'üstlerindeki', 'устьлерине' => 'üstlerine', 'устьлерини' => 'üstlerini',
+ 'устюрткъа' => 'üsturtqa', 'усьнюхаткъа' => 'üsnühatqa', 'усьнюхаты' => 'üsnühatı',
+ 'усьтю' => 'üstü', 'усьтюмде' => 'üstümde', 'усьтюмдеки' => 'üstümdeki', 'усьтюме' => 'üstüme',
+ 'усьтюнде' => 'üstünde', 'усьтюндеки' => 'üstündeki', 'усьтюндемиз' => 'üstündemiz',
+ 'усьтюне' => 'üstüne', 'усьтюни' => 'üstüni', 'усьтюнлик' => 'üstünlik',
+ 'усьтюнъизге' => 'üstüñizge', 'утёкунь' => 'ütökün', 'уфюрди' => 'üfürdi', 'учю' => 'üçü',
+ 'учюмиз' => 'üçümiz', 'учюн' => 'üçün', 'учюнджи' => 'üçünci', 'учюнджисининъ' => 'üçüncisiniñ',
+ 'ушюй' => 'üşüy', 'ушюмез' => 'üşümez', 'ушюмезсинъ' => 'üşümezsiñ',
+ 'факультетинде' => 'fakultetinde', 'факультетине' => 'fakultetine',
+ 'февральнинъ' => 'fevralniñ', 'харьковдаки' => 'harkovdaki', 'харьковдан' => 'harkovdan',
+ 'чёкти' => 'çökti', 'чёкюрли' => 'çökürli', 'чёкюч' => 'çöküç', 'чёллюкке' => 'çöllükke',
+ 'чёль' => 'çöl', 'чёльде' => 'çölde', 'чёльмек' => 'çölmek', 'чёткю' => 'çötkü',
+ 'чёчамийлер' => 'çöçamiyler', 'чюнки' => 'çünki', 'чюрюди' => 'çürüdi', 'чюрюк' => 'çürük',
+ 'шукюр' => 'şükür', 'шукюрлер' => 'şükürler', 'этюв' => 'etüv', 'этювден' => 'etüvden',
+ 'этюви' => 'etüvi', 'этюдлар' => 'etüdlar', 'юзден' => 'yüzden', 'юзлеп' => 'yüzlep',
+ 'юзлерини' => 'yüzlerini', 'юзлернен' => 'yüzlernen', 'юзлюги' => 'yüzlügi',
+ 'юзлюкке' => 'yüzlükke', 'юзю' => 'yüzü', 'юзюм' => 'yüzüm', 'юзюме' => 'yüzüme',
+ 'юзюмен' => 'yüzümen', 'юзюмни' => 'yüzümni', 'юзюнде' => 'yüzünde', 'юзюни' => 'yüzüni',
+ 'юзюнинъ' => 'yüzüniñ', 'юзюнъ' => 'yüzüñ', 'юзюнъизге' => 'yüzüñizge', 'юклю' => 'yüklü',
+ 'юксельтюв' => 'yükseltüv', 'юньлю' => 'yünlü', 'юньлюдже' => 'yünlüce',
+ 'юртсеверлик' => 'yurtseverlik', 'юртюде' => 'yürtüde', 'юрьтю' => 'yürtü',
+ 'юрьтюге' => 'yürtüge', 'юрьтюнинъ' => 'yürtüniñ', 'юрюльсе' => 'yürülse', 'юрюнъиз' => 'yürüñiz',
+ 'юрюш' => 'yürüş', 'юрюши' => 'yürüşi', 'юрюшим' => 'yürüşim', 'юрюшини' => 'yürüşini',
+ 'юрюшнен' => 'yürüşnen', 'юрюшни' => 'yürüşni',
+ ];
+
+ # map Cyrillic to Latin and back, whole word match only
+ # no variants: map exactly as is
+ # items with capture group refs (e.g., $1) are only mapped from the
+ # regex to the reference
+ private $exactCaseMappings = [
+ # аббревиатуры
+ # abbreviations
+ 'ОБСЕ' => 'OBSE', 'КъМДж' => 'QMC', 'КъАЭ' => 'QAE', 'ГъСМК' => 'ĞSMK', 'ШСДжБ' => 'ŞSCB',
+ 'КъМШСДж' => 'QMŞSC', 'КъДМПУ' => 'QDMPU', 'КъМПУ' => 'QMPU', 'КъЮШ' => 'QYŞ', 'ЮШ' => 'YŞ',
+ ];
+
+ # map Cyrillic to Latin and back, match end of word
+ # variants: all lowercase, all uppercase, first letter capitalized
+ # "first letter capitalized" variant was in the source
+ # items with capture group refs (e.g., $1) are only mapped from the
+ # regex to the reference
+ private $suffixMapping = [
+ # originally C2L
+ 'иаль' => 'ial', 'нуль' => 'nul', 'кой' => 'köy', 'койнинъ' => 'köyniñ', 'койни' => 'köyni',
+ 'койге' => 'köyge', 'койде' => 'köyde', 'койдеки' => 'köydeki', 'койден' => 'köyden',
+ 'козь' => 'köz',
+
+ # originally L2C, here swapped
+ 'етсин' => 'etsin',
+
+ ];
+
+ # map Cyrillic to Latin and back, match beginning of word
+ # variants: all lowercase, all uppercase, first letter capitalized
+ # items with capture group refs (e.g., $1) are only mapped from the
+ # regex to the reference
+ private $prefixMapping = [
+ # originally C2L
+ 'буюк([^ъ])' => 'büyük$1', 'бую([гдйлмнпрстчшc])(и)' => 'büyü$1$2',
+ 'буют([^ыа])' => 'büyüt$1', 'джонк([^ъ])' => 'cönk$1', 'коюм' => 'köyüm', 'коюнъ' => 'köyüñ',
+ 'коюн([ди])' => 'köyün$1', 'куе' => 'küye', 'куркке' => 'kürkke', 'куркни' => 'kürkni',
+ 'куркте' => 'kürkte', 'куркчи' => 'kürkçi', 'куркчю' => 'kürkçü',
+
+ # арабизмы на муи- муэ- / Arabic муи- муэ-
+ 'му([иэИЭ])' => 'mü$1',
+
+ # originally L2C, here swapped
+ 'итъаль' => 'ital',
+ 'роль$1' => 'rol([^ü])',
+ 'усть$1' => 'üst([knt])',
+
+ ];
+
+ private $Cyrl2LatnRegexes = [];
+ private $Latn2CyrlRegexes = [];
+
+ function loadRegs() {
+ // Regexes as keys need to be declared in a function.
+ $this->Cyrl2LatnRegexes = [
+ ############################
+ # относятся ко всему слову #
+ # whole words #
+ ############################
+ '/\b([34])(\-)юнджи\b/u' => '$1$2ünci',
+ '/\b([34])(\-)ЮНДЖИ\b/u' => '$1$2ÜNCİ',
+
+ # отдельно стоящие Ё и Я
+ # stand-alone Ё and Я
+ '/\bЯ\b/u' => 'Ya',
+ '/\bЁ\b/u' => 'Yo',
+
+ ############################
+ # относятся к началу слова #
+ # word prefixes #
+ ############################
+ '/\bКъЮШн/u' => 'QYŞn',
+ '/\bЮШн/u' => 'YŞn',
+
+ # о => ö
+ '/\b(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3$4',
+ '/\bо(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2$3',
+ '/\b(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' =>
+ '$1Ö$2$3$4',
+ '/\bО(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2$3',
+
+ '/\b(['.Crh::C_M_CONS.'])о(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ö$2$3',
+ '/\bо(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ö$1$2',
+ '/\b(['.Crh::C_M_CONS.'])О(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ö$2$3',
+ '/\bО(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ö$1$2',
+
+ # ё => yö
+ '/\bё(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2$3',
+ '/\bЁ(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2$3',
+ '/\bЁ(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2$3',
+ '/\bё(['.Crh::C_CONS.'])([ьеюü])/u' => 'yö$1$2',
+ '/\bЁ(['.Crh::C_CONS_LC.'])([ьеюü])/u' => 'Yö$1$2',
+ '/\bЁ(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => 'YÖ$1$2',
+
+ # у => ü, ую => üyü
+ '/\b(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3$4',
+ '/\bу(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2$3',
+ '/\bую(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2$3',
+ '/\b(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' =>
+ '$1Ü$2$3$4',
+ '/\bУ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2$3',
+ '/\bУю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2$2',
+ '/\bУЮ(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2$3',
+
+ '/\b(['.Crh::C_M_CONS.'])у(['.Crh::C_CONS.'])([еиэюьü])/u' => '$1ü$2$3',
+ '/\bу(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ü$1$2',
+ '/\bую(['.Crh::C_CONS.'])([еиэюьü])/u' => 'üyü$1$2',
+ '/\b(['.Crh::C_M_CONS.'])У(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => '$1Ü$2$3',
+ '/\bУ(['.Crh::C_CONS.'])([еиэюьüЕИЭЮЬÜ])/u' => 'Ü$1$2',
+ '/\bУю(['.Crh::C_CONS.'])([еиэюьü])/u' => 'Üyü$1$2',
+ '/\bУЮ(['.Crh::C_CONS.'])([еиэюьü])/u' => 'ÜYÜ$1$2',
+
+ # ю => yü
+ '/\b([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3$4',
+ '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3$4',
+ '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3$4',
+ '/\b([аыоуеиёюАЫОУЕИЁЮ]?)ю(['.Crh::C_CONS.'])([ьеюü])/u' => '$1yü$2$3',
+ '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_LC.'])([ьеюü])/u' => '$1Yü$2$3',
+ '/\b([АЫОУЕИЁЮ]?)Ю(['.Crh::C_CONS_UC.'])([ЬЕЮÜ])/u' => '$1YÜ$2$3',
+
+ # e => ye, я => ya
+ '/\bе/u' => 'ye',
+ '/\bЕ(['.Crh::C_LC.'cğñqöü])/u' => 'Ye$1',
+ '/\bЕ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YE$1',
+ '/\bя/u' => 'ya',
+ '/\bЯ(['.Crh::C_LC.'cğñqöü])/u' => 'Ya$1',
+ '/\bЯ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YA$1',
+ '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])е/u' => '$1ye',
+ '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_LC.'cğñqöü])/u' => '$1Ye$2',
+ '/([аеёиоуыэюяйьъaeöüАЕЁИОУЫЭЮЯЙЬЪAEÖÜ])Е(['.Crh::C_UC.'CĞÑQÖÜ])/u' => '$1YE$2',
+ '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])я/u' => '$1ya',
+ '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я(['.Crh::C_LC.'cğñqöü])/u' => '$1Ya$2',
+ '/([аеёиоуыэюяйьъaeöüğqАЕЁИОУЫЭЮЯЙЬЪAEÖÜĞQ])Я(['.Crh::C_UC.'CĞÑQÖÜ])/u' => '$1YA$2',
+
+ ###############################
+ # не зависят от места в слове #
+ # position independent #
+ ###############################
+
+ # слова на -льон
+ # words with -льон
+ '/льон/u' => 'lyon',
+ '/ЛЬОН/u' => 'LYON',
+
+ '/козь([^я])/u' => 'köz$1',
+ '/Козь([^я])/u' => 'Köz$1',
+ '/КОЗЬ([^Я])/u' => 'KÖZ$1',
+
+ # Ö, Ü 1-й заход: ё, ю после согласных > ö, ü
+ # Ö, Ü 1st instance: ё, ю after consonants > ö, ü
+ '/(['.Crh::C_CONS.'])ю/u' => '$1ü',
+ '/(['.Crh::C_CONS.'])Ю/u' => '$1Ü',
+ '/(['.Crh::C_CONS.'])ё/u' => '$1ö',
+ '/(['.Crh::C_CONS.'])Ё/u' => '$1Ö',
+
+ # остальные вхождения о, у, ё, ю
+ # other occurences of о, у, ё, ю
+ '/Ё(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YO$2',
+ '/Ю(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'YU$2',
+
+ # Ц & Щ
+ '/Ц(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'TS$2',
+ '/Щ(['.Crh::C_UC.'CĞÑQÖÜ])/u' => 'ŞÇ$2',
+ ];
+
+ $this->Latn2CyrlRegexes = [
+ # буква Ё - первый заход
+ # расставляем Ь после согласных
+ '/^([yY])ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|$)/u' => '$1ö$2ь$3',
+ '/^([yY])Ö(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|$)/u' => '$1Ö$2Ь$3',
+ '/^AQŞ(['.Crh::WORD_ENDS.'ngd])/u' => 'АКъШ$1',
+
+ # буква Ю - первый заход
+ # расставляем Ь после согласных
+ '/^([yY])ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|$)/u' => '$1ü$2ь$3',
+ '/^([yY])Ü(['.Crh::L_N_CONS.'])([aAuU'.Crh::L_CONS.']|$)/u' => '$1Ü$2Ь$3',
+
+ '/^([bcgkpşBCGKPŞ])ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1ö$2ь$3',
+ '/^([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1Ö$2Ь$3',
+ '/^([bcgkpşBCGKPŞ])Ö(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1Ö$2Ь$3',
+ '/^([bcgkpşBCGKPŞ])ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1ü$2ь$3',
+ '/^([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1Ü$2Ь$3',
+ '/^([bcgkpşBCGKPŞ])Ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => '$1Ü$2Ь$3',
+
+ # ö и ü в начале слова
+ # случаи, когда нужен Ь
+ '/^ö(['.Crh::L_N_CONS.'pP])(['.Crh::L_CONS.']|$)/u' => 'ö$1ь$2',
+ '/^Ö(['.Crh::L_N_CONS_LC.'p])(['.Crh::L_CONS.']|$)/u' => 'Ö$1ь$2',
+ '/^Ö(['.Crh::L_N_CONS_UC.'P])(['.Crh::L_CONS.']|$)/u' => 'Ö$1Ь$2',
+ '/^ü(['.Crh::L_N_CONS.'])(['.Crh::L_CONS.']|$)/u' => 'ü$1ь$2',
+ '/^Ü(['.Crh::L_N_CONS_LC.'])(['.Crh::L_CONS.']|$)/u' => 'Ü$1ь$2',
+ '/^Ü(['.Crh::L_N_CONS_UC.'])(['.Crh::L_CONS.']|$)/u' => 'Ü$1Ь$2',
+
+ '/ts$/u' => 'ц',
+ '/şç$/u' => 'щ',
+ '/Ş[çÇ]$/u' => 'Щ',
+ '/T[sS]$/u' => 'Ц',
+
+ # Ь после Л
+ # add Ь after Л
+ '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|$)/u' => '$1ль$2',
+ '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|$)/u' => '$1ЛЬ$2',
+
+ # относятся к началу слова
+ '/^ts/u' => 'ц',
+ '/^T[sS]/u' => 'Ц',
+
+ '/^şç/u' => 'щ',
+ '/^Ş[çÇ]/u' => 'Щ',
+
+ # Э
+ '/(^|['.Crh::L_VOW.'аеэяАЕЭЯ])e/u' => '$1э',
+ '/(^|['.Crh::L_VOW_UC.'АЕЭЯ])E/u' => '$1Э',
+
+ '/^(['.Crh::L_M_CONS.'])ö/u' => '$1о',
+ '/^(['.Crh::L_M_CONS.'])Ö/u' => '$1О',
+ '/^(['.Crh::L_M_CONS.'])ü/u' => '$1у',
+ '/^(['.Crh::L_M_CONS.'])Ü/u' => '$1У',
+
+ '/^ö/u' => 'о',
+ '/^Ö/u' => 'О',
+ '/^ü/u' => 'у',
+ '/^Ü/u' => 'У',
+
+ # некоторые исключения
+ # some exceptions
+ '/maal([^e])/u' => 'мааль$1',
+ '/Maal([^e])/u' => 'Мааль$1',
+ '/MAAL([^E])/u' => 'МААЛЬ$1',
+ '/küf([^eü])/u' => 'куфь$1',
+ '/Küf([^eü])/u' => 'Куфь$1',
+ '/KÜF([^EÜ])/u' => 'КУФЬ$1',
+ '/köz([^eü])/u' => 'козь$1',
+ '/Köz([^eü])/u' => 'Козь$1',
+ '/KÖZ([^EÜ])/u' => 'КОЗЬ$1',
+
+ # Punctuation
+ '/#|No\./' => '№',
+
+ # некоторые случаи употребления Ц
+ '/tsi([^zñ])/u' => 'ци$1',
+ '/T[sS][iİ]([^zZñÑ])/u' => 'ЦИ$1',
+ '/ts([ou])/u' => 'ц$1',
+ '/T[sS]([oOuU])/u' => 'Ц$1',
+ '/ts(['.Crh::L_CONS.'])/u' => 'ц$1',
+ '/T[sS](['.Crh::L_CONS.'])/u' => 'Ц$1',
+ '/(['.Crh::L_CONS.'])ts/u' => '$1ц',
+ '/(['.Crh::L_CONS.'])T[sS]/u' => '$1Ц',
+ '/tsиал/u' => 'циал',
+ '/TSИАЛ/u' => 'ЦИАЛ',
+
+ # убираем ьi
+ # remove ьi (note Cyrillic ь and Latin i)
+ '/[ьЬ]([iİ])/u' => '$1',
+
+ # ya & ye
+ '/(['.Crh::L_CONS.'])ya/u' => '$1ья',
+ '/(['.Crh::L_CONS.'])Y[aA]/u' => '$1ЬЯ',
+ '/(['.Crh::L_CONS.'])ye/u' => '$1ье',
+ '/(['.Crh::L_CONS.'])Y[eE]/u' => '$1ЬЕ',
+
+ # расставляем Ь перед Ё
+ # place Ь in front of Ё
+ '/(['.Crh::L_CONS.'])y[oö]/u' => '$1ьё',
+ '/(['.Crh::L_CONS.'])Y[oOöÖ]/u' => '$1ЬЁ',
+ # оставшиеся вхождения yo и yö
+ # remaining occurrences of yo and yö
+ '/y[oö]/u' => 'ё',
+ '/[yY][oOöÖ]/u' => 'Ё',
+
+ # расставляем Ь перед Ю
+ # place Ь in front of Ю
+ '/(['.Crh::L_CONS.'])y[uü]/u' => '$1ью',
+ '/(['.Crh::L_CONS.'])Y[uUüÜ]/u' => '$1ЬЮ',
+ # оставшиеся вхождения yu и yü
+ # remaining occurrences of yu and yü
+ '/y[uü]/u' => 'ю',
+ '/[yY][uUüÜ]/u' => 'Ю',
+
+ # убираем ьa
+ # remove ьa (note Cyrillic ь and Latin a)
+ '/[ьЬ]([aA])/u' => '$1',
+
+ # дж
+ '/C(['.Crh::L_UC.Crh::C_UC.'Ъ])/u' => 'ДЖ$1',
+
+ # гъ, къ, нъ
+ # гъ, къ, нъ
+ '/Ğ(['.Crh::L_UC.Crh::C_UC.'Ъ])/u' => 'ГЪ$1',
+ '/Q(['.Crh::L_UC.Crh::C_UC.'Ъ])/u' => 'КЪ$1',
+ '/Ñ(['.Crh::L_UC.Crh::C_UC.'Ъ])/u' => 'НЪ$1',
+
+ ];
+ }
+
+ private $CyrlCleanUpRegexes = [
+ '/([клнрст])ь\1/u' => '$1$1',
+ '/([КЛНРСТ])Ь\1/u' => '$1$1',
+ '/К[ьЬ]к/u' => 'Кк',
+ '/Л[ьЬ]л/u' => 'Лл',
+ '/Н[ьЬ]н/u' => 'Нн',
+ '/Р[ьЬ]р/u' => 'Рр',
+ '/С[ьЬ]с/u' => 'Сс',
+ '/Т[ьЬ]т/u' => 'Тт',
+
+ # убираем ьы и ь..ы
+ # remove ьы и ь..ы
+ '/[ьЬ]ы/u' => 'ы',
+ '/ЬЫ/u' => 'Ы',
+ '/[ьЬ]([гдклмнпрстчшГДКЛМНПРСТЧШ])ы/u' => '$1ы',
+ '/Ь([гдклмнпрстчшГДКЛМНПРСТЧШ])Ы/u' => '$1Ы',
+ '/[ьЬ]([гкнГКН])([ъЪ])ы/u' => '$1$2ы',
+ '/Ь([ГКН])ЪЫ/u' => '$1ЪЫ',
+
+ # убираем йь
+ # remove йь
+ '/йь/u' => 'й',
+ '/ЙЬ/u' => 'Й',
+
+ # частичное решение проблемы слова юз - 100
+ # Partial solution of the problem of the word юз ("100")
+ # notice that these are cross-word patterns
+ '/эки юзь/u' => 'эки юз', '/Эки юзь/u' => 'Эки юз', '/ЭКИ ЮЗЬ/u' => 'ЭКИ ЮЗ',
+ '/учь юзь/u' => 'учь юз', '/Учь юзь/u' => 'Учь юз', '/УЧЬ ЮЗЬ/u' => 'УЧЬ ЮЗ',
+ '/дёрт юзь/u' => 'дёрт юз', '/Дёрт юзь/u' => 'Дёрт юз', '/ДЁРТ ЮЗЬ/u' => 'ДЁРТ ЮЗ',
+ '/беш юзь/u' => 'беш юз', '/Беш юзь/u' => 'Беш юз', '/БЕШ ЮЗЬ/u' => 'БЕШ ЮЗ',
+ '/алты юзь/u' => 'алты юз', '/Алты юзь/u' => 'Алты юз', '/АЛТЫ ЮЗЬ/u' => 'АЛТЫ ЮЗ',
+ '/еди юзь/u' => 'еди юз', '/Еди юзь/u' => 'Еди юз', '/ЕДИ ЮЗЬ/u' => 'ЕДИ ЮЗ',
+ '/секиз юзь/u' => 'секиз юз', '/Секиз юзь/u' => 'Секиз юз', '/СЕКИЗ ЮЗЬ/u' => 'СЕКИЗ ЮЗ',
+ '/докъуз юзь/u' => 'докъуз юз', '/Докъуз юзь/u' => 'Докъуз юз', '/ДОКЪУЗ ЮЗЬ/u' => 'ДОКЪУЗ ЮЗ',
+ ];
+}
"rev-deleted-text-permission": "tina kasabelih masumad <strong> masipu </strong>.\nkapah tayza[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} misipu nasulitan nazipa’an] miala pulita cesyun.",
"rev-suppressed-text-permission": "tina kasabelih sumad nay <strong> masatezep paazih </strong>.\ntaneng tayza [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} satezep paazih nasulitan nazipa’an] maala pulita cesyun.",
"rev-deleted-text-unhide": "tina kasabelih a sumad nay <strong> masipu </strong>.\nkapah tayza [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} misipu nasulitan nazipa’an] maala pulita cesyun.\namahica kisu palalid, kapahtu kisu [$1 miciwsace tina sumad].",
- "rev-suppressed-text-unhide": "This page revision has been <strong>suppressed</strong>.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].\nYou can still [$1 view this revision] if you wish to proceed.",
+ "rev-suppressed-text-unhide": "tina kasabelih a sumad nay <strong> masatezep paazih </strong>。\nkapah tayza [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} satezep paazih nasulitan nazipa’an] miala pulita cesyun。\namahica kisu apalalid,kapah tu kisu [$1 miciwsace tina sumad]",
"rev-suppressed-text-view": "tina kasabelih a sumad nay <strong> masatezep paazih </strong>.\nkapah kisu lalid miciwsace misumad,kapah tayza [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} satezep paazih nazipa’an ] miala pulita cesyun.",
- "rev-deleted-no-diff": "zayhan kasabelih u cacay masumad nu ayaway mapa <strong>masipu</strong>, la’cus kisu miciwsace tu kasasizuma.",
+ "rev-deleted-no-diff": "zayhan kasabelih ilabu’ a cacay a sumad nu ayaway nay <strong> masipu tuway </strong>, la’cus kisu miciwsace sasizuma.\ntaneng tayza [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}] masipu nasulitan nazipa’an maala pulitaay a cesyun.",
"rev-suppressed-no-diff": "zayhan kasabelih ilabu’ a cacay a sumad nu ayaway nay <strong>masipu tuway</strong>, la’cus kisu miciwsace sasizuma.",
"rev-deleted-unhide-diff": "miciwsace sasizuma ilabu’ay ku cacay masumad nu ayaway nay <strong> masipu tu </strong>.\nkapah tyaza [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} masipu nasulitan nazipa’an] maala pulita kalunasulitan.\namahica kisu apalalid, kapah tu kisu [$1 miwsace tina zuma].",
"rev-suppressed-unhide-diff": "miciwsace sasizuma ilabu’ay a cacay masumad nu ayaway nay <strong>masatezep paazih</strong>.\nkapah tayza [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} satezep paazih nasulitan nazipa’an] maala pulitaya a cesyun.\namahica kisu palalid, kapah tu kisu [$1 miciwsace tina sasizuma].",
"recentchangesdays-max": "sayadahay $1 {{PLURAL:$1|a demiad}}",
"recentchangescount": "pataayaw tu kawaw paazihay nu mikawaway-kalumyiti nikayadah:",
"prefs-help-recentchangescount": "uyni yamalyilu capi demiad a sumad, kasabelih nasulitan-nazipa’an atu nazipa’an",
- "prefs-help-watchlist-token2": "miaca aazihan numisuay a miazihay a piazihan-tu-sulit maydihay a mima-sabuhat.\namahicahica tademaw matineng ku mama-sabuhat dada’ taneng maasip numisuay a miazihay a piazihan-tu-sulit,sisa amana kilul tu nizateng kasasimel tu zuma a tadeamw.\namahica izaw ku maydih [[Special:ResetTokens|kapah kisu miliyaw patizeng mima-sabuhat]].",
"savedprefs": "masuped setin tu kanamuhan nu misu.",
"savedrights": "masuped tu {{GENDER:$1|$1}} misaungayay a tungus.",
"timezonelegend": "tatukian a kakitizaan:",
"rcfilters-filterlist-noresults": "caykatepa sakacucek nu misapili’",
"rcfilters-noresults-conflict": "zayhan kilim sakacucek sasula’cus,cay katepa ku heci",
"rcfilters-state-message-subset": "tina sakacucek nu misapili’ inayi’ ku laheci, zayhan kya heci yamalyilu isasa’ subal saahebalay a {{PLURAL:$2|sakacucek nu misapili’}} cacay ku ilabu’ay (mitanam kasiwantan sacuzu’ amipili’):$1",
+ "rcfilters-state-message-fullcoverage": "mipili’ i luyaluy labu’ay sacahamin sakacucek nu misapili’ atu inayi’ mipili’ sa malecad, dayhiw tina sakacucek nu misapili’caay kalahci. luyaluy yamalyilu tu: $1",
"rcfilters-filtergroup-authorship": "paaninay a masacudaday",
"rcfilters-filter-editsbyself-label": "numisuay a mikawaway-kalumyiti",
"rcfilters-filter-editsbyself-description": "numisuay a paanin",
"rcfilters-filter-categorization-description": "mamicunus i kakuniza saca nay kakuniza masipuay a kasabelih nasulitanㄡ",
"rcfilters-filter-logactions-label": "saungay a nasulitan nazipa’an",
"rcfilters-filter-logactions-description": "mikuwan saungay, patizeng canghaw, misipu kasabelih, patapabaw...",
+ "rcfilters-hideminor-conflicts-typeofchange-global": "\"mikilulay mikawaway-kalumyiti\" a sakacucek nu misapili’ sasula’cus tu cacay saca yadah sumad nikalahizaan sakacucek nu misapili’,zayhan izaw hatizaay sumad nikalahizaan la’cus patuzu’ay tu \"mikilulay\". sasula’cusay a sakacucek nu misapili’ sacuzu’ tu i pabaw nu pisaungay a subal nu sakacucek nu misapili’.",
"rcfilters-hideminor-conflicts-typeofchange": "izaw ku zumaay misumad nikalahizaan la’cus matuzu’ay mala \"mikilulay\", sisa tina sakacucek nu misapili’ atu isasa’ay a sumad nikalahizaan sakacucek nu misapili’ sasula’cus: $1",
"rcfilters-typeofchange-conflicts-hideminor": "tina misumad nikalahizaan sakacucek nu misapili’ atu \"mikilulay mikawaway-kalumyiti\" sakacucek nu misapili’sasula’cus, uzuma misumad nikalahizaan la’cus matuzu’ay ku \"mikilulay\"",
"rcfilters-filtergroup-lastRevision": "sabaluhay masumad",
"wantedfiles": "maydihay a tangan",
"wantedfiletext-cat": "isasa’ay a tangan masaungay sa, uyzasa tangan inayi’. hekal suped-sulu a tangan kanahatu mueneng, uyzasa tina piazihan-tu-sulit apasilsil tuway. tina kakuniza pacebaay a tubeli kasacacay saka <del>sipu-kenis</del> sacuzu’. zuma sa, kasabelih sipakabit ilabu' tangan inayi’ apaazih i piazihan-tu-sulit [[:$1]].",
"wantedfiletext-cat-noforeign": "isasa’ay a tangan mapasaungay tu uyzasa inayi’ay. tina a dada’ silabas kakaiyan tu, kasabelih sipakabit ilabu’ nika inayi’ay a tangan mapalaylay i [[:$1]]",
+ "wantedfiletext-nocat": "isasa’ tangan masaungay sa, zumasatu tangan inayi’. hekal suped-sulu a tangan kanahatu, uyzasa tina piazihan-tu-sulit apasilsil tuway. uyniyan paceba’ay a kasacacay apacuzu’ ku <del> sipu-kenis </del> sacuzu’.",
"wantedtemplates": "maydihay a taazihan mitudung",
"mostlinked": "masasiket sayadahay a kasabelih",
"mostlinkedcategories": "masasiket sayadahay a kakuniza",
"file-info-size-pages": "$1 × $2 syangsu, hacica ku tabaki nu tangan:$3,MIME kakuniza: $4, $5 {{PLURAL:$5|ku kasabelih}}",
"file-nohires": "inay ku sangaleb takalaway a katingalaw, kapah tu nipabeli.",
"svg-long-desc": "SVG tangan, maazihay hacica ku tabaki $1 × $2 syangsu, tangan hacica ku tabaki: $3",
- "svg-long-desc-animated": "SVG tangan, maazihay hacica ku tabaki $1 × $2 syangsu, tangan hacica ku tabaki: $3",
+ "svg-long-desc-animated": "SVG kulit-iga tangan, maazihay hacica tabaki:$1 × $2 syangsu, tangan pinalu hacica tabaki: $3",
"svg-long-error": "la’cusay a SVG tangan: $1",
"show-big-image": "saayaway a tangan",
"show-big-image-preview": "pataayaway miazih hacica ku tabaki: $1.",
"diff-multi-sameuser": "({{PLURAL:$1|لا مراجعات متوسطة|مراجعة متوسطة واحدة|مراجعتان متوسطتان|$1 مراجعات متوسطة|$1 مراجعة متوسطة}} بواسطة نفس المستخدم غير {{PLURAL:$1|معروضة|معروضة|معروضتين|معروضة}})",
"diff-multi-otherusers": "({{PLURAL:$1|لا مراجعات|مراجعة متوسطة واحدة|مراجعتان متوسطتان|$1 مراجعات متوسطة|$1 مراجعة متوسطة}} بواسطة {{PLURAL:$2|ولا مستخدم|مستخدم واحد آخر|مستخدمين اثنين آخرين|$2 مستخدمين|$2 مستخدماً|$2 مستخدم}} غير {{PLURAL:$1|معروضة|معروضة|معروضتين|معروضة}})",
"diff-multi-manyusers": "({{PLURAL:$1||مراجعة واحدة متوسطة غير معروضة أجراها|مراجعتان متوسطتان غير معروضتان أجراهما|$1 مراجعات متوسطة غير معروضة أجراها|$1 مراجعة متوسطة غير معروضة أجراها}} أكثر من {{PLURAL:$2||مستخدم واحد|مستخدمين|$2 مستخدمين|$2 مستخدمًا|$2 مستخدم}}.)",
+ "diff-paragraph-moved-tonew": "الفقرة تم نقلها. اضغط للذهاب للموقع الجديد.",
+ "diff-paragraph-moved-toold": "الفقرة تم نقلها. اضغط للذهاب للموقع القديم.",
"difference-missing-revision": "{{PLURAL:$2|مراجعة واحدة|$2 مراجعات}} لهذا الفرق ($1) {{PLURAL:$2|لم|لم}} يتم إيجادها.\n\nهذا يحدث عادة عن طريق اتباع وصلة فرق قديمة لصفحة تم حذفها.\nالتفاصيل يمكن إيجادها في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
"searchresults": "نتائج البحث",
"searchresults-title": "نتائج البحث عن \"$1\"",
"recentchangesdays-max": "الحد الأقصى {{PLURAL:$1|أقل من يوم|يوم واحد|يومان|$1 أيام|$1 يوما|$1 يوم}}",
"recentchangescount": "عدد التعديلات الظاهرة مبدئيا:",
"prefs-help-recentchangescount": "بما في ذلك أحدث التغييرات وتاريخ الصفحات والسجلات.",
- "prefs-help-watchlist-token2": "هذا هو المفتاح السري لتغذية الويب لقائمة مراقبتك.\nيمكن لأي شخص يعرفه أن يقرأ قائمة مراقبتك، ولذا لا تتشاركه مع أحد. [[Special:ResetTokens|انقر هنا إذا أردت إعادة ضبطه]].",
"savedprefs": "تم حفظ تفضيلاتك.",
"savedrights": "حُفظت المجموعات الجديدة {{GENDER:$1|للمستخدم|للمستخدمة}} $1.",
"timezonelegend": "المنطقة الزمنية:",
"rcfilters-restore-default-filters": "استرجاع المرشحات الافتراضية",
"rcfilters-clear-all-filters": "مسح كل المرشحات",
"rcfilters-show-new-changes": "عرض أحدث التغييرات",
- "rcfilters-search-placeholder": "رشح التغييرات (استخدم القائمة أو البحث لاسم المرشح)",
+ "rcfilters-search-placeholder": "رشح التغييرات (استخدم القائمة أو ابحث عن اسم المرشح)",
"rcfilters-invalid-filter": "مرشح غير صحيح",
"rcfilters-empty-filter": "لا مرشحات فعالة. كل المساهمات معروضة.",
"rcfilters-filterlist-title": "مرشحات",
"diff-multi-sameuser": "(не {{PLURAL:$1|паказаная $1 прамежная вэрсія|паказаныя $1 прамежныя вэрсіі|паказаныя $1 прамежных вэрсіяў}} аўтарства таго ж удзельніка)",
"diff-multi-otherusers": "(не {{PLURAL:$1|паказаная $1 прамежная вэрсія|паказаныя $1 прамежныя вэрсіі|паказаныя $1 прамежных вэрсіяў}} аўтарства {{PLURAL:$2|1=яшчэ аднаго ўдзельніка|$2 удзельнікаў}})",
"diff-multi-manyusers": "($1 {{PLURAL:$1|прамежная вэрсія|прамежныя вэрсіі|прамежных вэрсіяў}} $2 {{PLURAL:$2|удзельніка|удзельнікаў|удзельнікаў}} {{PLURAL:$1|не паказаная|не паказаныя|не паказаныя}})",
+ "diff-paragraph-moved-tonew": "Параграф быў перанесены. Націсьніце, каб перайсьці ў новае месца.",
+ "diff-paragraph-moved-toold": "Параграф быў перанесены. Націсьніце, каб перайсьці ў першапачатковае месца.",
"difference-missing-revision": "{{PLURAL:$2|$2 вэрсія|$2 вэрсіі|$2 вэрсіяў}} з гэтымі адрозьненьнямі ($1) {{PLURAL:$2|не была|не былі}} знойдзеныя.\n\nЗвычайна гэта здараецца з-за пераходу па састарэлай спасылцы на старонку, якая была выдаленая.\nПадрабязнасьці можна знайсьці ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
"searchresults": "Вынікі пошуку",
"searchresults-title": "Вынікі пошуку для «$1»",
"recentchangesdays-max": "Максымальна $1 {{PLURAL:$1|дзень|дні|дзён}}",
"recentchangescount": "Колькасьць рэдагаваньняў для паказу па змоўчаньні:",
"prefs-help-recentchangescount": "Гэта ўключае апошнія зьмены, гісторыі старонак і журналы падзеяў.",
- "prefs-help-watchlist-token2": "Гэта сакрэтны ключ да стужкі вашага сьпісу назіраньня.\nКожны, хто ведае яго, можа атрымаць доступ да вашага сьпісу назіраньня, таму не дзяліцеся ім.\nКалі вам трэба, [[Special:ResetTokens|вы можаце скінуць яго]].",
"savedprefs": "Вашыя налады былі захаваныя.",
"savedrights": "Групы {{GENDER:$1|ўдзельніка|ўдзельніцы}} $1 былі захаваныя.",
"timezonelegend": "Часавы пояс:",
"email-blacklist-label": "Забараніць гэтым удзельнікам дасылаць мне лісты электроннай поштай:",
"prefs-searchoptions": "Пошук",
"prefs-namespaces": "Прасторы назваў",
- "default": "па змоÑ\9eÑ\87ванÑ\8cнÑ\96",
+ "default": "па змоўчаньні",
"prefs-files": "Файлы",
- "prefs-custom-css": "Ð\86ндÑ\8bвÑ\96дÑ\83алÑ\8cны CSS",
- "prefs-custom-js": "Ð\86ндÑ\8bвÑ\96дÑ\83алÑ\8cнÑ\8b JS",
+ "prefs-custom-css": "УлаÑ\81ны CSS",
+ "prefs-custom-js": "УлаÑ\81нÑ\8b JavaScript",
"prefs-common-css-js": "Агульны CSS/JS для ўсіх афармленьняў:",
"prefs-reset-intro": "Вы можаце выкарыстоўваць гэтую старонку для замены Вашых наладаў на налады сайта па змоўчваньні.\nГэтае дзеяньне не можа быць адмененае.",
"prefs-emailconfirm-label": "Пацьверджаньне адрасу электроннай пошты:",
"uploadstash-file-not-found-no-thumb": "Не атрымалася здабыць мініятуру.",
"uploadstash-file-not-found-no-local-path": "Няма лякальнага шляху да маштабаванага элемэнту.",
"uploadstash-file-not-found-no-object": "Не атрымалася стварыць лякальны аб’ект файлу для мініятуры.",
+ "uploadstash-file-not-found-no-remote-thumb": "Памылка атрыманьня мініятуры: $1\nURL = $2",
+ "uploadstash-file-not-found-missing-content-type": "Адсутнічае загаловак тыпу зьместу.",
"invalid-chunk-offset": "Няслушнае зрушэньне фрагмэнту",
"img-auth-accessdenied": "Доступ забаронены",
"img-auth-nopathinfo": "Адсутнічае PATH_INFO.\nВаш сэрвэр не ўстаноўлены на пропуск гэтай інфармацыі.\nМагчма, ён працуе праз CGI і не падтрымлівае img_auth.\nГлядзіце https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
"diff-multi-sameuser": "(একই ব্যবহারকারী দ্বারা সম্পাদিত {{PLURAL:$1|একটি মধ্যবর্তী সংশোধন|$1টি মধ্যবর্তী সংশোধন}} দেখানো হচ্ছে না)",
"diff-multi-otherusers": "({{PLURAL:$2|একজন|$2 জন}} ব্যবহারকারী দ্বারা সম্পাদিত {{PLURAL:$1|একটি|$1টি}} মধ্যবর্তী সংশোধন দেখানো হচ্ছে না)",
"diff-multi-manyusers": "($2 জনের বেশি {{PLURAL:$2|ব্যবহারকারীর}} সম্পাদিত {{PLURAL:$1|একটি মধ্যবর্তী সংশোধন|$1টি মধ্যবর্তী সংশোধন}} প্রদর্শিত হচ্ছে না)",
+ "diff-paragraph-moved-tonew": "অনুচ্ছেদ স্থানান্তর করা হয়েছে। নতুন অবস্থানে যাওয়ার জন্য ক্লিক করুন।",
+ "diff-paragraph-moved-toold": "অনুচ্ছেদ স্থানান্তর করা হয়েছে। পুরনো অবস্থানে যাওয়ার জন্য ক্লিক করুন।",
"difference-missing-revision": "এই পার্থক্যের ($1) অন্তর্গত {{PLURAL:$2|একটি সংশোধিত সংস্করণ|$2টি সংশোধিত সংস্করণ}} খুঁজে পাওয়া যাচ্ছে না।\n\nসাধারণত মুছে ফেলা হয়েছে এমন পাতার মেয়াদ উত্তীর্ণ ইতিহাস পাতার লিংক খোলার কারণে এটি হতে পারে। \n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} পাতা অবলুপ্তি লগে] বিস্তারিত তথ্য জানা যাবে।",
"searchresults": "অনুসন্ধানের ফলাফল",
"searchresults-title": "\"$1\" অনুসন্ধানের ফলাফল",
"recentchangesdays-max": "সর্বোচ্চ $1 {{PLURAL:$1|দিনের}}",
"recentchangescount": "সাম্প্রতিক পরিবর্তনে প্রদর্শিত সম্পাদনার পূর্বনির্ধারিত সংখ্যা:",
"prefs-help-recentchangescount": "এতে সাম্প্রতিক পরিবর্তনগুলি, পাতার ইতিহাসগুলি এবং লগগুলি অন্তর্ভুক্ত।",
- "prefs-help-watchlist-token2": "এটি আপনার নজরতালিকার ওয়েব ফিডের গোপন চাবি। কেউ যদি এটি জানতে পারেন, তাহলে তিনি আপনার নজরতালিকা পড়তে সক্ষম হবেন, তাই এটি প্রকাশ করবেন না। [[Special:ResetTokens|আপনার এটি পুনঃনির্ধারণ করার প্রয়োজন হলে এখানে ক্লিক করুন]]।",
"savedprefs": "আপনার পছন্দগুলি সংরক্ষণ করা হয়েছে।",
"savedrights": "{{GENDER:$1|$1}}-এর ব্যবহারকারী দল সংরক্ষিত হয়েছে।",
"timezonelegend": "সময় অঞ্চল:",
"htmlform-selectorother-other": "অন্য",
"htmlform-no": "না",
"htmlform-yes": "হ্যাঁ",
- "htmlform-chosen-placeholder": "à¦\85পশন নির্বাচন করুন",
+ "htmlform-chosen-placeholder": "বিà¦\95লà§\8dপ নির্বাচন করুন",
"htmlform-cloner-create": "আরও যোগ করুন",
"htmlform-cloner-delete": "অপসারণ",
"htmlform-cloner-required": "অন্তত একটি মূল্য আবশ্যক।",
"underline-never": "Morse",
"underline-default": "Merdeer dre ziouer",
"editfont-style": "Stil font an takad skridaozañ :",
- "editfont-default": "Diouzh ar merdeer",
"editfont-monospace": "Font unesaouennet",
"editfont-sansserif": "Font hep-serif",
"editfont-serif": "Font serif",
"explainconflict": "Enrollet eo bet ar bajenn-mañ war-lerc'h m'ho pefe kroget d'he c'hemmañ.\nE-krec'h an takad aozañ emañ an destenn evel m'emañ enrollet bremañ er bank roadennoù.\nHo kemmoù deoc'h a zeu war wel en takad aozañ traoñ.\nRet e vo deoc'h degas ho kemmoù d'an destenn zo evit poent.\nN'eus '''nemet''' an destenn zo en takad krec'h a vo saveteet pa klikot war \"$1\".",
"yourtext": "Ho testenn",
"storedversion": "Stumm enrollet",
- "nonunicodebrowser": "'''DIWALLIT: N'eo ket skoret an Unicode gant ho merdeer. Un diskoulm da c'hortoz zo bet kavet evit ma c'hallfec'h kemmañ pennadoù : dont a raio war wel an arouezennoù an-ASCII er prenestr skridaozañ evel kodoù eizhdekvedennel.'''",
"editingold": "'''Diwallit : o kemm ur stumm kozh eus ar bajenn-mañ emaoc'h. Mard enrollit bremañ e vo kollet an holl gemmoù bet graet abaoe ar stumm-se.'''",
"yourdiff": "Diforc'hioù",
"copyrightwarning": "Sellet e vez ouzh an holl degasadennoù graet war {{SITENAME}} evel ouzh degasadennoù a zouj da dermenoù ar $2 (Sellet ouzh $1 evit gouzout hiroc'h). Mar ne fell ket deoc'h e vefe embannet ha skignet ho skridoù, arabat kas anezho.<br />\nHeñveldra, prometiñ a rit kemer perzh dre zegas skridoù savet ganeoc'h hepken pe tennet eus ur vammenn frank a wirioù.\n'''NA IMPLIJIT KET LABOURIOÙ GANT GWIRIOÙ AOZER (COPYRIGHT) HEP AOTRE D'OBER KEMENT-SE!'''",
"recentchangesdays-max": "D'ar muiañ $1 {{PLURAL:$1|deiz|deiz}}",
"recentchangescount": "Niver a gemmoù da ziskouez dre ziouer",
"prefs-help-recentchangescount": "Kemer a ra an dra-mañ e kont ar c'hemmoù diwezhañ, istor ar pajennoù hag ar marilhoù.",
- "prefs-help-watchlist-token2": "Homañ zo an alc'hwez kuzh d'ho roll-evezhiañ davit boued war ar web. Forzh piv a anavez anezhañ a c'hall lenn ho roll-evezhiañ, setu na lavarit grit diwar e benn. M'ho pez ezhomm, e c'hallit [[Special:ResetTokens|assevel anezhañ]].",
"savedprefs": "Enrollet eo bet ar penndibaboù.",
"savedrights": "Enrollet eo bet strolladoù implijer {{GENDER:$1|$1}}.",
"timezonelegend": "Takad eur :",
"rcfilters-group-results-by-page": "Strollañ an disoc'hoù dre bajenn",
"rcfilters-grouping-title": "O strollañ",
"rcfilters-activefilters": "Siloù oberiant",
+ "rcfilters-advancedfilters": "Siloù araokaet",
+ "rcfilters-limit-title": "Kemmoù da vezañ diskouezet",
+ "rcfilters-limit-shownum": "Diskouez {{PLURAL:$1|ar c'hemm|an $1 kemm}} diwezhañ",
"rcfilters-days-title": "Deizioù paseet",
"rcfilters-hours-title": "Eurioù paseet",
"rcfilters-days-show-days": "($1 {{PLURAL:$1|deiz}})",
"rcfilters-days-show-hours": "$1 {{PLURAL:$1|eur}}",
"rcfilters-highlighted-filters-list": "Lakaet war wel : $1",
"rcfilters-quickfilters": "Siloù enrollet",
- "rcfilters-quickfilters-placeholder-title": "Liamm ebet enrollet evit c'hoazh",
+ "rcfilters-quickfilters-placeholder-title": "Sil ebet enrollet evit c'hoazh",
"rcfilters-savedqueries-defaultlabel": "Siloù enrollet",
"rcfilters-savedqueries-rename": "Adenvel",
"rcfilters-savedqueries-setdefault": "Gweredekaat dre ziouer",
"rcfilters-savedqueries-remove": "Dilemel",
"rcfilters-savedqueries-new-name-label": "Anv",
"rcfilters-savedqueries-apply-label": "Enrollañ an arventennoù",
+ "rcfilters-savedqueries-apply-and-setdefault-label": "Krouiñ ur sil dre ziouer",
"rcfilters-savedqueries-cancel-label": "Nullañ",
"rcfilters-savedqueries-add-new-title": "Enrollañ arventennoù ar sil en implij",
"rcfilters-restore-default-filters": "Assevel ar siloù dre ziouer",
"rcfilters-clear-all-filters": "Riñsañ an holl siloù",
+ "rcfilters-show-new-changes": "Gwelet ar c'hemmoù diwezhañ",
"rcfilters-search-placeholder": "Silañ ar c'hemmoù diwezhañ (merdeiñ pe kregiñ da skrivañ)",
"rcfilters-invalid-filter": "Sil direizh",
"rcfilters-empty-filter": "Sil oberiant ebet. War wel emañ an holl gemmoù.",
"rcfilters-filterlist-title": "Siloù",
- "rcfilters-filterlist-whatsthis": "Petra eo se ?",
+ "rcfilters-filterlist-whatsthis": "Penaos ez a en-dro ?",
"rcfilters-filterlist-feedbacklink": "Reiñ ho soñj diwar-benn ar siloù (beta) nevez",
"rcfilters-highlightbutton-title": "Lakaat an disoc'hoù war wel",
"rcfilters-highlightmenu-title": "Dibabit ul liv",
"rcfilters-filter-user-experience-level-unregistered-label": "Divarilh",
"rcfilters-filter-user-experience-level-unregistered-description": "Aozerien n'int ket kevreet.",
"rcfilters-filter-user-experience-level-newcomer-label": "Tud nevez-deuet",
- "rcfilters-filter-user-experience-level-newcomer-description": "Nebeutoc'h eget 10 kemm ha 4 devezh obererezh.",
+ "rcfilters-filter-user-experience-level-newcomer-description": "Aozerien enrollet ganto nebeutoc'h eget 10 kemm pe 4 devezh obererezh.",
"rcfilters-filter-user-experience-level-learner-label": "Deskarded",
- "rcfilters-filter-user-experience-level-learner-description": "Muioc'h a skiant-prenet eget an \"deraouidi\" hogen nebeutoc'h eget an \"implijerien arroutet\".",
+ "rcfilters-filter-user-experience-level-learner-description": "Aozerien ganto muioc'h a skiant-prenet eget an \"deraouidi\" hogen nebeutoc'h eget an \"implijerien arroutet\".",
"rcfilters-filter-user-experience-level-experienced-label": "Implijerien arroutet",
- "rcfilters-filter-user-experience-level-experienced-description": "Ouzhpenn 30 devezh oberiantiz ha 500 kemm.",
+ "rcfilters-filter-user-experience-level-experienced-description": "Aozerien graet ganto ouzhpenn 500 kemm ha dezho 30 devezh oberiantiz .",
"rcfilters-filtergroup-automated": "Degasadennoù emgefre",
"rcfilters-filter-bots-label": "Robot",
"rcfilters-filter-bots-description": "Kemmoù graet gant ostilhoù emgefre.",
"rcfilters-filter-watchlist-watched-label": "War ar roll evezhiañ",
"rcfilters-filter-watchlist-watched-description": "Kemmoù graet war pajennoù ho roll evezhiañ.",
"rcfilters-filter-watchlist-watchednew-label": "Kemmoù nevez er roll evezhiañ",
+ "rcfilters-filter-watchlistactivity-unseen-label": "Kemmoù n'int ket bet gwelet",
+ "rcfilters-filter-watchlistactivity-seen-label": "Kemmoù bet gwelet",
"rcfilters-filtergroup-changetype": "Seurt kemm",
"rcfilters-filter-pageedits-label": "Kemmoù pajennoù",
"rcfilters-filter-pageedits-description": "Kemmoù da danvez ar wiki, d'ar c'haozeadennoù, da zeskrivadurioù rummadoù...",
"block": "Stankañ an implijer",
"unblock": "Distankañ an implijer",
"blockip": "Stankañ an {{GENDER:$1|implijer|implijerez}}",
- "blockip-legend": "Stankañ an implijer",
"blockiptext": "Grit gant ar furmskrid a-is evit stankañ ar moned skrivañ ouzh ur chomlec'h IP pe un implijer bennak.\nSeurt diarbennoù n'hallont bezañ kemeret nemet evit mirout ouzh ar vandalerezh hag a-du gant ar [[{{MediaWiki:Policy-url}}|reolennoù da vezañ heuliet]].\nRoit a-is an abeg resis (o verkañ, da skouer, roll ar pajennoù bet graet gaou outo).\nGallout a rit stankañ lijorennoù chomlec'hioù IP en ur ober gant an ereadur [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] syntax; /$1 eo al lijorenn hirañ aotreet evit IPv4 ha /$2 evit IPv6.",
"ipaddressorusername": "Chomlec'h IP pe anv implijer",
"ipbexpiry": "Pad ar stankadenn",
"compare-title-not-exists": "N'eus ket eus an titl spisaet ganeoc'h.",
"compare-revision-not-exists": "N'eus ket eus an adweladenn spisaet ganeoc'h.",
"diff-form": "ur '''furmskrid'''",
+ "permanentlink": "Peurliamm",
"dberr-problems": "Ho tigarez ! Kudennoù teknikel zo gant al lec'hienn-mañ.",
"dberr-again": "Gortozit un nebeud munutennoù a-raok adkargañ.",
"dberr-info": "(Dibosupl kevreañ ouzh an diaz roadennoù : $1)",
"gotointerwiki-invalid": "Direizh eo an titl merket",
"gotointerwiki-external": "Emaoc'h war-nes kuitaat {{SITENAME}} evit mont da welet [[$2]] hag a zo ul lec'hienn all a-ziforc'h.\n\n[$1 Klikañ amañ evit kenderc'hel war $1].",
"undelete-cantedit": "N'hallit ket diziverkañ ar bajenn-mañ rak n'oc'h ket aotreet da gemmañ anezhi.",
- "undelete-cantcreate": "N'hallit ket diziverkañ ar bajenn-mañ rak n'eus pajenn ebet gant an anv-mañ ha n'oc'h ket aotreet da grouiñ ar bajenn-mañ."
+ "undelete-cantcreate": "N'hallit ket diziverkañ ar bajenn-mañ rak n'eus pajenn ebet gant an anv-mañ ha n'oc'h ket aotreet da grouiñ ar bajenn-mañ.",
+ "pagedata-title": "Roadennoù ar bajenn",
+ "pagedata-bad-title": "Titl direizh : $1."
}
"recentchangesdays-max": "(màxim $1 {{PLURAL:$1|dia|dies}})",
"recentchangescount": "Nombre d'edicions a mostrar per defecte:",
"prefs-help-recentchangescount": "Inclou els canvis recents, els historials de pàgines i els registres.",
- "prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, així que no la compartiu.\n[[Special:ResetTokens|Cliqueu aquí si voleu restaurar-la]].",
"savedprefs": "S’han desat les vostres preferències.",
"savedrights": "S'han desat els grups d'usuari de {{GENDER:$1|$1}}.",
"timezonelegend": "Fus horari:",
"recentchangesdays-max": "Къезиг $1 {{PLURAL:$1|дена}}",
"recentchangescount": "Ӏадйитаран кепаца гойтуш долу нисдарийн дукхалла",
"prefs-help-recentchangescount": "Гойту керла нисдарш, агӀонийн истори, тептарш.",
- "prefs-help-watchlist-token2": "Иза хьан тергаме могӀан къайла догӀа ду.\nМуьлха и хуучунна йиш ю хьан тергаме могӀам беша, цундела ма хаийта иза кхечаьрга. [[Special:ResetTokens|ТӀетаӀа йе кхуза и хьайга кхосса лууш делахь]].",
"savedprefs": "Хьан гӀирс Ӏалашбина.",
"savedrights": "{{GENDER:$1|$1}} декъашхочун бакъонаш Ӏалашйина.",
"timezonelegend": "Сахьтан аса:",
"pageinfo-robot-index": "Магийна",
"pageinfo-robot-noindex": "Магийна дац",
"pageinfo-watchers": "Хьоьжучера дукхалла",
+ "pageinfo-visiting-watchers": "АгӀона тидамбеш болу а, хийцамаш гуш болу а декъашхой",
"pageinfo-few-watchers": "{{PLURAL:$1|ТӀаьхьадогӀучерал}} $1 кӀезиг",
"pageinfo-redirects-name": "ХӀокху агӀон тӀе йолу дӀассахьажорийн дукхалла",
"pageinfo-subpages-name": "ХӀокху агӀона бухара агӀонаш",
"pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|цӀе хийцар|цӀе хийцарш}}; $3 {{PLURAL:$3|гуттар хуьлург|гуттар хуьлурш}})",
- "pageinfo-firstuser": "АгӀо кхуллург",
+ "pageinfo-firstuser": "АгӀо кхоьллинарг",
"pageinfo-firsttime": "АгӀо кхоьллина терахь",
"pageinfo-lastuser": "ТӀеххьара тадар дийнарг",
"pageinfo-lasttime": "ТӀеххьара нисдар дина терахь",
"compare-invalid-title": "Ахьа язйина йолу цӀе ца магайо.",
"compare-title-not-exists": "Иштта цӀе яц.",
"compare-revision-not-exists": "Иштта версеш яц.",
+ "diff-form": "Башхаллаш",
+ "diff-form-oldid": "Версин шира идентификатор (тӀехь дац)",
+ "diff-form-revid": "Башхаллаш йолу версин идентификатор",
+ "diff-form-submit": "Схьагайта башхаллаш",
"dberr-problems": "Бехк ма бил! ХӀокху сайтехь техникан халонаш хила.",
"dberr-again": "Хьажа карла йаккха агlо массех минот йаьлча.",
"dberr-info": "(аьтто ца хили зӀе хӀотта серверца бухара хаамашца: $1)",
"minutes-abbrev": "$1дакъ.",
"hours-abbrev": "$1саат",
"bad_image_list": "Формат бойле олмалы:\n\nЭр сатыр * ишаретинен башламалы. Сатырнынъ биринджи багълантысы къошмагъа ясакълангъан файлгъа багъланмалы.\nШу сатырда илеридеки багълантылар истисна олурлар, яни шу саифелерде ишбу файл къулланмакъ мумкюн.",
+ "variantname-crh": "Lat./Кир.",
+ "variantname-crh-latn": "Latin",
+ "variantname-crh-cyrl": "Кирил",
"metadata": "Ресим деталлери",
"metadata-help": "Файлда (адетиндже ракъамлы камера ве сканерлернен къошулгъан) иляве малюматы бар. Эгер бу файл яратылгъандан сонъ денъиштирильсе эди, бельки де базы параметрлер эскирди.",
"metadata-expand": "Тафсилятны косьтер",
"minutes-abbrev": "$1daq.",
"hours-abbrev": "$1saat",
"bad_image_list": "Format böyle olmalı:\n\nEr satır * işaretinen başlamalı. Satırnıñ birinci bağlantısı qoşmağa yasaqlanğan faylğa bağlanmalı.\nŞu satırda ilerideki bağlantılar istisna olur, yani şu saifelerde işbu fayl qullanmaq mümkün.",
+ "variantname-crh": "Lat./Кир.",
+ "variantname-crh-latn": "Latin",
+ "variantname-crh-cyrl": "Кирил",
"metadata": "Resim detalleri",
"metadata-help": "Faylda (adetince raqamlı kamera ve skanerlernen qoşulğan) ilâve malümatı bar. Eger bu fayl yaratılğandan soñ deñiştirilse edi, belki de bazı parametrler eskirdi.",
"metadata-expand": "Tafsilâtnı köster",
"toc": "Obsah",
"showtoc": "zobrazit",
"hidetoc": "skrýt",
- "collapsible-collapse": "Sbalit",
- "collapsible-expand": "Rozbalit",
+ "collapsible-collapse": "sbalit",
+ "collapsible-expand": "rozbalit",
"confirmable-confirm": "Jste si {{GENDER:$1|jist|jista|jisti}}?",
"confirmable-yes": "Ano",
"confirmable-no": "Ne",
"recentchangesdays-max": "Maximálně $1 {{PLURAL:$1|den|dny|dní}}",
"recentchangescount": "Počet implicitně zobrazovaných záznamů:",
"prefs-help-recentchangescount": "Týká se posledních změn, historie stránek a protokolovacích záznamů.",
- "prefs-help-watchlist-token2": "Toto je tajný klíč k webovému kanálu vašich sledovaných stránek. Kdokoli, kdo bude tento klíč znát, bude moci váš seznam sledovaných stránek číst, takže ho nešiřte.\n[[Special:ResetTokens|Kliknutím sem ho můžete reinicializovat.]]",
"savedprefs": "Nastavení byla uložena.",
"savedrights": "Skupiny {{GENDER:$1|uživatele|uživatelky}} $1 byly uloženy.",
"timezonelegend": "Časové pásmo:",
"diff-multi-sameuser": "({{PLURAL:$1|Eine dazwischenliegende Version desselben Benutzers wird|$1 dazwischenliegende Versionen desselben Benutzers werden}} nicht angezeigt)",
"diff-multi-otherusers": "({{PLURAL:$1|Eine dazwischenliegende Version|$1 dazwischenliegende Versionen}} von {{PLURAL:$2|einem anderen Benutzer|$2 Benutzern}} {{PLURAL:$1|wird|werden}} nicht angezeigt)",
"diff-multi-manyusers": "({{PLURAL:$1|$1 dazwischenliegende Versionen}} von mehr als {{PLURAL:$2|$2 Benutzern}}, die nicht angezeigt werden)",
+ "diff-paragraph-moved-tonew": "Der Absatz wurde verschoben. Klicken, um zur neuen Stelle zu springen.",
+ "diff-paragraph-moved-toold": "Der Absatz wurde verschoben. Klicken, um zur alten Stelle zu springen.",
"difference-missing-revision": "{{PLURAL:$2|Eine Version|$2 Versionen}} dieser Unterschiedsanzeige ($1) {{PLURAL:$2|wurde|wurden}} nicht gefunden.\n\nDieser Fehler wird normalerweise von einem veralteten Link zur Versionsgeschichte einer Seite verursacht, die zwischenzeitlich gelöscht wurde.\nEinzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Lösch-Logbuch] vorhanden.",
"searchresults": "Suchergebnisse",
"searchresults-title": "Suchergebnisse für „$1“",
"prefs-watchlist-edits": "Maximale Anzahl der angezeigten Einträge:",
"prefs-watchlist-edits-max": "Maximal 1.000 Einträge",
"prefs-watchlist-token": "Token der Beobachtungsliste:",
+ "prefs-watchlist-managetokens": "Token verwalten",
"prefs-misc": "Verschiedenes",
"prefs-resetpass": "Passwort ändern",
"prefs-changeemail": "E-Mail-Adresse ändern oder entfernen",
"recentchangesdays-max": "Maximal $1 {{PLURAL:$1|Tag|Tage}}",
"recentchangescount": "Anzahl der standardmäßig angezeigten Bearbeitungen:",
"prefs-help-recentchangescount": "Dies umfasst die Liste der letzten Änderungen, die Versionsgeschichte und die Logbücher.",
- "prefs-help-watchlist-token2": "Dies ist der geheime Schlüssel zum Webfeed deiner Beobachtungsliste.\nJeder, der ihn kennt, kann deine Beobachtungsliste lesen. Teile ihn deshalb nicht Anderen mit.\nSofern notwendig, [[Special:ResetTokens|kannst du ihn zurücksetzen]].",
+ "prefs-help-tokenmanagement": "Du kannst den geheimen Schlüssel für dein Benutzerkonto ansehen und zurücksetzen, der auf den Webfeed deiner Beobachtungsliste zugreifen kann. Jeder, der den Schlüssel kennt, kann deine Beobachtungsliste lesen. Deshalb teile ihn nicht anderen mit.",
"savedprefs": "Deine Einstellungen wurden gespeichert.",
"savedrights": "Die Benutzergruppen von {{GENDER:$1|$1}} wurden gespeichert.",
"timezonelegend": "Zeitzone:",
"recentchangesdays-max": "Tewr zaf $1 {{PLURAL:$1|roc|roci}}",
"recentchangescount": "Halê est-amardışi ra mocnayışi rê amarê vırnayışan:",
"prefs-help-recentchangescount": "Ney de vurnayışê peyêni, tarixê pelan u cıkewteni asenê.",
- "prefs-help-watchlist-token2": "Na pawıtış nımnayi kılta listada şımaya.\nOke kıliti zano şeno listeya tamaşann bıvino. Poğta coy ra kesiya me hesırne. \n[[Special:ResetTokens|Na kıliti reset kerdışi re tiyay bıploğne]].",
"savedprefs": "Tecihê şıma qeyd biy.",
"savedrights": "{{GENDER:$1|$1}} gruba karberi qeyd biya.",
"timezonelegend": "Warey saete:",
"underline-never": "कभैई नाई",
"underline-default": "खोल और ब्राउजर निर्धारित",
"editfont-style": "फन्ट प्रकार क्षेत्र सम्पादन गर:",
- "editfont-default": "ब्राउजर पूर्वस्थिति",
"editfont-monospace": "मोनोस्पेस्ड फन्ट",
"editfont-sansserif": "सान्स-सेरिफ फन्ट",
"editfont-serif": "सेरिफ फन्ट",
"nosuchusershort": " \"$1\" नाउँ भयाः कोइलै प्रयोगकर्ता नाइथिन।\n तमरो हिज्जे जाँचः।",
"nouserspecified": "प्रयोगकर्ता नाम दिनु अनिवार्य छ।",
"login-userblocked": "ये प्रयोगकर्तालाई रोक लगाया छ। प्रवेश गददु अनुमति छैन।",
- "wrongpassword": "पासवरà¥\8dड à¤\97लत हालियà¥\8b।\nà¤\95à¥\83पया à¤\86à¤\9cà¥\80 पà¥\8dरयास à¤\97रया।",
+ "wrongpassword": "à¤\97लत पà¥\8dरयà¥\8bà¤\95à¥\8dता नाà¤\89à¤\81 या पासवरà¥\8dड हालियà¥\8b।\nà¤\95à¥\83पया à¤\86à¤\81à¤\9cà¥\80 पà¥\8dरयास à¤\97रà¥\8dâ\80\8dयाà¤\83।",
"wrongpasswordempty": "हालिएया पासवर्ड खालि थ्यो।\nकृपया आजी प्रयास गरया।",
"passwordtooshort": "पासवर्ड कम्तिमालै {{PLURAL:$1|१ अक्षर|$1 अक्षरन}}को हुनुपडन्छ।",
"passwordtoolong": "पासवर्ड {{PLURAL:$1|१ अक्षर|$1 अक्षरन}} है लामो हुननाइसक्दो।",
"watchlisttools-view": "आधारित फेरबदलीहरू हेर",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|कुरडी]])",
"specialpages": "खास पन्नाअन",
- "specialpages-note": "* साधारण खास पानाहरू।\n* <span class=\"mw-specialpagerestricted\">निषेधित खास पानाहरू।</span>",
"specialpages-group-changes": "अल्लैका परिवर्तन लगहरू",
"tags": "मान्य परिवर्तन ट्यागहरू",
"tag-filter": "[[Special:Tags|पुछड]] छानिन्या",
"recentchangesdays-max": "Mâsim $1 {{PLURAL:$1|dé}}",
"recentchangescount": "Nómer ed mudéfichi da fêr vèder per default:",
"prefs-help-recentchangescount": "A gh'é dèinter al j ûltmi mudéfichi, stôri, e regéster.",
- "prefs-help-watchlist-token2": "Còsta l'é la cêva secrēta p'r al flós web di tō tgnû 'd ôc specêl. Tót quî che la cgnòsen a sràn bòun ed lēşer i tō tgnû 'd ôc specêl, per còst an spartîrla mìa cun nisûn. [[Special:ResetTokens|Cléca ché s'ét ghê bişògn ed turnêrla impustêr]].",
"savedprefs": "Al preferèinsi în stêdi salvêdi.",
"timezonelegend": "Fûş urâri:",
"localtime": "Ōra lochêla:",
"diff-multi-sameuser": "({{PLURAL:$1|Μία ενδιάμεση αναθεώρηση|$1 ενδιάμεσες αναθεωρήσεις}} από τον ίδιο χρήστη δεν εμφανίζεται)",
"diff-multi-otherusers": "({{PLURAL:$1|Μία ενδιάμεση έκδοση|$1 ενδιάμεσες εκδόσεις}} από {{PLURAL:$2|ένα χρήστη|$2 χρήστες}} δεν εμφανίζ{{PLURAL:$1|εται|ονται}})",
"diff-multi-manyusers": "({{PLURAL:$1|Μία ενδιάμεση αναθεώρηση|$1 ενδιάμεσες αναθεωρήσεις}} από περισσότερο από $2 {{PLURAL:$2|χρήστη|χρήστες}} δεν εμφανίζ{{PLURAL:$1|εται|ονται}})",
+ "diff-paragraph-moved-tonew": "Η παράγραφος αφαιρέθηκε. Κάντε κλικ για να πάτε σε νέα τοποθεσία.",
+ "diff-paragraph-moved-toold": "Η παράγραφος αφαιρέθηκε. Πατήστε στο κουμπί για να πάτε σε προηγούμενη τοποθεσία.",
"difference-missing-revision": "{{PLURAL:$2|Μία αναθεώρηση|$2 αναθεωρήσεις}} αυτής της διαφοράς ($1) δεν {{PLURAL:$2|μπόρεσε να βρεθεί|μπόρεσαν να βρεθούν}}.\n\nΑυτό συνήθως προκαλείται από παλιό σύνδεσμο διαφοράς προς σελίδα που έχει διαγραφεί.\nΛεπτομέρειες θα βρείτε στο [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ημερολόγιο καταγραφής διαγραφών].",
"searchresults": "Αποτελέσματα αναζήτησης",
"searchresults-title": "Αποτελέσματα αναζήτησης για \"$1\"",
"recentchangesdays-max": "($1 {{PLURAL:$1|ημέρα|ημέρες}} το μέγιστο)",
"recentchangescount": "Αριθμός επεξεργασιών που να εμφανίζονται για προεπιλογή.",
"prefs-help-recentchangescount": "Αυτό περιλαμβάνει τις πρόσφατες αλλαγές, τα ιστορικά των σελίδων, και τα αρχεία διαγραφών.",
- "prefs-help-watchlist-token2": "Αυτό είναι το μυστικό κλειδί για την web τροφοδοσία της λίστας παρακολούθησής σας.\nΌποιος το γνωρίζει θα είναι σε θέση να διαβάσει την λίστα παρακολούθησης σας, οπότε μην τον μοιράζεστε.\n[[Special:ResetTokens|Κάνε κλικ εδώ εάν θέλετε να τον επαναφέρετε]].",
"savedprefs": "Οι προτιμήσεις σας έχουν αποθηκευτεί.",
"savedrights": "Οι ομάδες χρηστών {{GENDER:$1|του $1|της $1}} έχουν αποθηκευτεί.",
"timezonelegend": "Ζώνη ώρας:",
"diff-multi-sameuser": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} by the same user not shown)",
"diff-multi-otherusers": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} by {{PLURAL:$2|one other user|$2 users}} not shown)",
"diff-multi-manyusers": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} by more than $2 {{PLURAL:$2|user|users}} not shown)",
+ "diff-paragraph-moved-tonew": "Paragraph was moved. Click to jump to new location.",
+ "diff-paragraph-moved-toold": "Paragraph was moved. Click to jump to old location.",
"difference-missing-revision": "{{PLURAL:$2|One revision|$2 revisions}} of this difference ($1) {{PLURAL:$2|was|were}} not found.\n\nThis is usually caused by following an outdated diff link to a page that has been deleted.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
"search-summary": "",
"searchresults": "Search results",
"prefs-watchlist-edits": "Maximum number of changes to show in watchlist:",
"prefs-watchlist-edits-max": "Maximum number: 1000",
"prefs-watchlist-token": "Watchlist token:",
+ "prefs-watchlist-managetokens": "Manage tokens",
"prefs-misc": "Misc",
"prefs-resetpass": "Change password",
"prefs-changeemail": "Change or remove email address",
"recentchangesdays-max": "Maximum $1 {{PLURAL:$1|day|days}}",
"recentchangescount": "Number of edits to show by default:",
"prefs-help-recentchangescount": "This includes recent changes, page histories, and logs.",
- "prefs-help-watchlist-token2": "This is the secret key to the web feed of your watchlist.\nAnyone who knows it will be able to read your watchlist, so do not share it.\nIf you need to, [[Special:ResetTokens|you can reset it]].",
+ "prefs-help-tokenmanagement": "You can see and reset the secret key for your account that can access the Web feed of your watchlist. Anyone who knows the key will be able to read your watchlist, so do not share it.",
"savedprefs": "Your preferences have been saved.",
"savedrights": "The user groups of {{GENDER:$1|$1}} have been saved.",
"timezonelegend": "Time zone:",
"variantname-uz": "uz",
"variantname-uz-latn": "uz-Latn",
"variantname-uz-cyrl": "uz-Cyrl",
+ "variantname-crh": "crh",
+ "variantname-crh-latn": "crh-Latn",
+ "variantname-crh-cyrl": "crh-Cyrl",
"metadata": "Metadata",
"metadata-help": "This file contains additional information, probably added from the digital camera or scanner used to create or digitize it.\nIf the file has been modified from its original state, some details may not fully reflect the modified file.",
"metadata-expand": "Show extended details",
"recentchangesdays-max": "(maksimume $1 {{PLURAL:$1|tago|tagoj}})",
"recentchangescount": "Nombro de redaktoj por montri defaŭlte:",
"prefs-help-recentchangescount": "Ĉi tiu inkluzivas lastajn ŝanĝojn, paĝajn historiojn, kaj protokolojn.",
- "prefs-help-watchlist-token2": "Tio estas la sekreta ŝlosilo al la retfluo de via atentaro.\nĈiu, kiu konas ĝin, povas legi vian atentaron. Do, ne kunhavigu ĝin.\nSe vi devas, [[Special:ResetTokens|vi povas rekomencigi ĝin]].",
"savedprefs": "Viaj preferoj estas konservitaj.",
"savedrights": "La uzanto-grupoj de {{GENDER:$1|$1}} estis konservitaj.",
"timezonelegend": "Horzono:",
"nosuchusershort": "Ez dago \"$1\" izena duen erabiltzailerik. Egiaztatu ongi idatzi duzula.",
"nouserspecified": "Erabiltzaile izena zehaztu beharra daukazu.",
"login-userblocked": "Erabiltzailea blokeatua dago. Ezin du saioa hasi.",
- "wrongpassword": "Pasahitza ez da zuzena. Saiatu berriz.",
+ "wrongpassword": "Erabiltzailea edo pasahitza txarto sartu egin da. Saiatu berriz.",
"wrongpasswordempty": "Pasahitza hutsik dago. Saiatu berriz.",
"passwordtooshort": "Pasahitzek {{PLURAL:$1|karaktere 1|$1 karaktere}} gutxienez eduki behar dituzte.",
"passwordtoolong": "Pasahitzak ezin dira {{PLURAL:$1|karaktere bat|$1 karaktere}} baino luzeagoak izan.",
"diff-multi-sameuser": "(Erabiltzaile berdinaren {{PLURAL:$1|erdiko ekarpen bat ez da|$1 erdiko ekarpen ez dira}} erakusten)",
"diff-multi-otherusers": "({{PLURAL:$1|Tarteko berrikusketa bat|$1 tarteko berrikusketak}} {{PLURAL:$2|beste erabiltzaile bat|$2 erabiltzaileak}} egina ez da erakusten)",
"diff-multi-manyusers": "({{PLURAL:$1|Tarteko berrikusketa bat|$1 tarteko berrikusketak}} by more than $2 {{PLURAL:$2|erabiltzaile batek|erabiltzaile batzuek}} baino gehiagok egina ez erakutsia)",
+ "diff-paragraph-moved-tonew": "Paragrafoa mugitu egin da. Egin klik beste kokaleku batera salto egiteko.",
"difference-missing-revision": " ($1) ezberdinatasunaren {{PLURAL:$2|Berrikusketa bat|$2 berrikusketa}} ez {{PLURAL:$2|da|dira}} aurkitu.\n\nHau, orokorrean ezabatu egin den orri batera deskonektatua dagoen esteka desegonkor baten ondorioz gertatzen da.\n\nHemen xehetasunak aurki daitezke: [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
"searchresults": "Bilaketaren emaitzak",
"searchresults-title": "«$1» bilaketaren emaitzak",
"recentchangesdays-max": "(gehienez {{PLURAL:$1|egun bat|$1 egun}})",
"recentchangescount": "Erakusteko aldaketa kopurua, lehenetsita:",
"prefs-help-recentchangescount": "Honek azken aldaketak, orrialdeen historiak eta logak barne-biltzen ditu.",
- "prefs-help-watchlist-token2": "Hau da zure jarraipen zerrendako web jarioaren giltza sekretua.\nEzagutzen duen orok zure jarraipen zerrenda irakurtzeko aukera izango du, ez partekatu.\n[[Special:ResetTokens|Klik egin hemen berrezarri behar baduzu]]",
"savedprefs": "Zure hobespenak gorde egin dira.",
"savedrights": "{{GENDER:$1|$1}} erabiltzailearen taldeak gorde dira.",
"timezonelegend": "Ordu-eremua:",
"recentchangesdays-max": "Enintään $1 {{PLURAL:$1|päivä|päivää}}",
"recentchangescount": "Näytettävien muutoksien määrä oletuksena",
"prefs-help-recentchangescount": "Tämä sisältää tuoreet muutokset, muutoshistoriat ja lokit.",
- "prefs-help-watchlist-token2": "Tämä on salainen avain tarkkailulistasi verkkosyötteeseen.\nKuka tahansa, joka tietää sen voi lukea tarkkailulistaasi, joten älä paljasta sitä.\n[[Special:ResetTokens|Napsauta tästä, jos sinun pitää uudistaa se]].",
"savedprefs": "Asetuksesi on tallennettu.",
"savedrights": "Käyttäjän {{GENDER:$1|$1}} käyttäjäryhmät on tallennettu.",
"timezonelegend": "Aikavyöhyke",
"rollback-success": "Käyttäjän {{GENDER:$3|$1}} tekemät muokkaukset kumottiin ja sivu palautettiin käyttäjän {{GENDER:$4|$2}} versioon.",
"rollback-success-notify": "Kumottiin käyttäjän $1 muokkaukset; palautettiin viimeiseen käyttäjän $2 versioon. [$3 Näytä muutokset]",
"sessionfailure-title": "Istuntovirhe",
- "sessionfailure": "Istuntosi kanssa on ongelma. Muutosta ei toteutettu varotoimena istuntokaappauksien takia. Käytä selaimen paluutoimintoa ja päivitä sivu, jolta tulit, ja yritä uudelleen.",
+ "sessionfailure": "Näyttää siltä, että tämänhetkisessä istunnossasi on jokin ongelma. \nTämä toiminto on peruutettu varotoimena, jotta estetään istunnon kaappaaminen.\nMene aikaisemmalle sivulle ja päivitä se. Yritä sitten uudelleen.",
"changecontentmodel": "Muuta sivun sisältömallia",
"changecontentmodel-legend": "Muuta sisältömallia",
"changecontentmodel-title-label": "Sivun otsikko",
"diff-multi-sameuser": "({{PLURAL:$1|Une révision intermédiaire par le même utilisateur non affichée|$1 révisions intermédiaires par le même utilisateur non affichées}})",
"diff-multi-otherusers": "({{PLURAL:$1|Une révision intermédiaire|$1 révisions intermédiaires}} par {{PLURAL:$2|un autre utilisateur|$2 utilisateurs}} non {{PLURAL:$1|affichée|affichées}})",
"diff-multi-manyusers": "({{PLURAL:$1|Une révision intermédiaire|$1 révisions intermédiaires}} par plus {{PLURAL:$2|d'un utilisateur|de $2 utilisateurs}} {{PLURAL:$1|est masquée|sont masquées}})",
+ "diff-paragraph-moved-tonew": "Le paragraphe a été déplacé. Cliquez pour accéder au nouvel emplacement.",
+ "diff-paragraph-moved-toold": "Le paragraphe a été déplacé. Cliquez pour accéder à l'ancien emplacement.",
"difference-missing-revision": "{{PLURAL:$2|Une révision|$2 révisions}} de cette différence ($1) {{PLURAL:$2|n’a pas été trouvée|n’ont pas été trouvées}}.\n\nCela survient en général en suivant un lien de différence désuet vers une page qui a été supprimée.\nVous pouvez trouver des détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
"searchresults": "Résultats de la recherche",
"searchresults-title": "Résultats de recherche pour « $1 »",
"recentchangesdays-max": "(maximum $1 jour{{PLURAL:$1||s}})",
"recentchangescount": "Nombre de modifications à afficher par défaut :",
"prefs-help-recentchangescount": "Ceci inclut les modifications récentes, les pages d'historiques et les journaux.",
- "prefs-help-watchlist-token2": "Voici la clé secrète du flux Web de votre liste de suivi.\nToute personne la connaissant pourra lire votre liste de suivi, ne la communiquez donc pas.\n[[Special:ResetTokens|Cliquez ici si vous devez la réinitialiser]].",
"savedprefs": "Les préférences ont été sauvegardées.",
"savedrights": "Les droits utilisateur de {{GENDER:$1|$1}} ont été enregistrés.",
"timezonelegend": "Fuseau horaire :",
"tooltip-ca-edit": "આ પાનામાં ફેરફાર કરો",
"tooltip-ca-addsection": "નવો વિભાગ ઉમેરો",
"tooltip-ca-viewsource": "આ પાનુ સુરક્ષિત છે.\nતમે તેનો સ્રોત જોઇ શકો છો",
- "tooltip-ca-history": "àª\86 પાનાનાàª\82 àª\85àª\97ાàª\89નાàª\82 ફà«\87રફારà«\8b",
+ "tooltip-ca-history": "àª\86 પાનાનà«\80 àª\85àª\97ાàª\89નà«\80 àª\86વà«\83તà«\8dતિàª\93",
"tooltip-ca-protect": "આ પાનું સુરક્ષિત કરો",
"tooltip-ca-unprotect": "આ પાનું રક્ષણ બદલો",
"tooltip-ca-delete": "આ પાનું હટાવો",
"diff-multi-sameuser": "({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של אותו משתמש {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})",
"diff-multi-otherusers": "({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של {{PLURAL:$2|משתמש אחר אחד|$2 משתמשים}} {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})",
"diff-multi-manyusers": "({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של יותר {{PLURAL:$2|ממשתמש אחד|מ־$2 משתמשים}} {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})",
+ "diff-paragraph-moved-tonew": "הפיסקה הועברה. ניתן ללחוץ כאן כדי לעבור למיקומה החדש.",
+ "diff-paragraph-moved-toold": "הפיסקה הועברה. ניתן ללחוץ כאן כדי לעבור למיקומה הישן.",
"difference-missing-revision": "{{PLURAL:$2|גרסה אחת|$2 גרסאות}} מתוך הגרסאות שביקשת להשוות ($1) {{PLURAL:$2|לא נמצאה|לא נמצאו}}.\n\nזה נגרם בדרך־כלל עקב לחיצה על קישור ישן להבדלים בין גרסאות של דף שנמחק.\nאפשר למצוא פרטים ב[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} יומן המחיקות].",
"searchresults": "תוצאות החיפוש",
"searchresults-title": "תוצאות החיפוש \"$1\"",
"prefs-watchlist-edits": "המספר המרבי של העריכות שמוצגות ברשימת המעקב:",
"prefs-watchlist-edits-max": "לכל היותר: 1,000",
"prefs-watchlist-token": "אסימון לרשימת המעקב:",
+ "prefs-watchlist-managetokens": "ניהול אסימונים",
"prefs-misc": "שונות",
"prefs-resetpass": "שינוי סיסמה",
"prefs-changeemail": "שינוי או הסרת כתובת דוא\"ל",
"recentchangesdays-max": "לכל היותר {{PLURAL:$1|יום אחד|יומיים|$1 ימים}}",
"recentchangescount": "מספר העריכות שמוצגות כברירת מחדל:",
"prefs-help-recentchangescount": "ההעדפה הזאת כוללת את דף השינויים האחרונים, דפי היסטוריית גרסאות ויומנים.",
- "prefs-help-watchlist-token2": "זהו המפתח הסודי להזנה של רשימת המעקב שלך.\nכל מי שיודע אותו יכול לקרוא את רשימת המעקב שלך, לכן אין לשתף אותו.\nבמקרה הצורך, אפשר [[Special:ResetTokens|לאפס את האסימון]].",
+ "prefs-help-tokenmanagement": "באפשרותך לצפות במפתח הסודי לחשבונך, שמאפשר גישה ל־Feed האינטרנטי של רשימת המעקב שלך, ולאפס אותו. כל מי שיודע את המפתח יכול לקרוא את רשימת המעקב שלך, לכן אין לשתף אותו.",
"savedprefs": "ההעדפות שלך נשמרו.",
"savedrights": "קבוצות {{GENDER:$1|המשתמש|המשתמשת}} של \"$1\" נשמרו.",
"timezonelegend": "אזור זמן:",
"recentchangesdays-max": "(maksimalno $1 {{PLURAL:$1|dan|dana}})",
"recentchangescount": "Zadani broj izmjena koje se prikazuju:",
"prefs-help-recentchangescount": "Ovo uključuje nedavne promjene, stare izmjene, i evidencije.",
- "prefs-help-watchlist-token2": "Ovo je tajni ključ prema sažetku Vašeg popisa praćenja. Svaki suradnik kojem je poznat, moći će čitati Vaš popis praćenih stranica. Ne dijelite ga ni s kim. [[Special:ResetTokens|Kliknite ovdje ako ga želite ponovo postaviti]].",
"savedprefs": "Vaše postavke su sačuvane.",
"savedrights": "Suradnička su prava {{GENDER:$1|suradnika $1|suradnice $1}} spremljena.",
"timezonelegend": "Vremenska zona:",
"recentchangesdays-max": "($1 {{PLURAL:$1|օրից|օրից}} ոչ ավել)",
"recentchangescount": "Խմբագրումների թիվը ըստ լռության.",
"prefs-help-recentchangescount": "Ներառում է վերջին փոփոխությունները, էջերի պատմությունը և տեղեկամատյանները։",
- "prefs-help-watchlist-token2": "Սա գաղտնի բանալի է հսկականկի օգնույամբ նորություն ստանալու համար:\nՈվ որ գիտի այն կարող է կարդալ ձեր հսկացանկը, ուստի մի տարածեք այն:\nԵթե ձեզ պետք է զրոյացնել հսկացանկի կտրոնը, [[Special:ResetTokens| սեղմեք այստեղ]]:",
"savedprefs": "Ձեր նախընտրությունները հիշված են։",
"timezonelegend": "Ժամային գոտի.",
"localtime": "Տեղական ժամանակ.",
"metadata": "Մետատվյալներ",
"metadata-help": "Նիշքը պարունակում է ընդարձակ տվյալները, հավանաբար ավելացված թվային լուսանկարչական ապարատի կամ սկաների կողմից, որոնք օգտագործվել են նկարը ստեղծելու կամ թվայնացնելու համար։\nԵթե նիշքը ձևափոխվել է ստեղծումից ի վեր, ապա որոշ տվյալները կարող են չհամապատասխանել ձևափոխված նիշքին։",
"metadata-expand": "Ցուց տալ ընդարձակ տվյալները",
- "metadata-collapse": "Ô¹Õ¡Ö\84Ö\81Õ¶Õ¥Õ¬ Õ¨Õ¶Õ¤Õ¡Ö\80Õ±Õ¡Õ¯ Õ¿Õ¾ÕµÕ¬Õ¡ները",
+ "metadata-collapse": "Ô¹Õ¡Ö\84Ö\81Õ¶Õ¥Õ¬ Õ¬Ö\80Õ¡Ö\81Õ¸Ö\82Ö\81Õ«Õ¹ Õ¿Õ¾ÕµÕ¡Õ¬ները",
"metadata-fields": "EXIF մետատվյալների այն դաշտերը, որոնք նշված ենք այս ուղերձի մեջ, կցուցադրվեն պատկերի էջում, երբ մետատվյալների աղյուսակը ծալված է։ Այլ տվյալները լռությամբ կթաքցվեն։\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
"exif-imagewidth": "Լայնք",
"exif-imagelength": "Բարձրություն",
"diff-multi-sameuser": "({{PLURAL:$1|Un version intermedie|$1 versiones intermedie}} facite per le mesme usator non es monstrate)",
"diff-multi-otherusers": "({{PLURAL:$1|Un version intermedie|$1 versiones intermedie}} facite per {{PLURAL:$2|un altere usator|$2 usatores}} non es monstrate)",
"diff-multi-manyusers": "({{PLURAL:$1|Un version intermedie|$1 versiones intermedie}} facite per plus de $2 {{PLURAL:$2|usator|usatores}} non es monstrate)",
+ "diff-paragraph-moved-tonew": "Le paragrapho ha essite displaciate. Clicca pro saltar al nove position.",
"difference-missing-revision": "{{PLURAL:$2|Un version|$2 versiones}} de iste differentia ($1) non ha essite trovate.\n\nIsto es generalmente causate per sequer un ligamine de diff obsolete a un pagina que ha essite delite.\nDetalios se trova in le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de deletiones].",
"searchresults": "Resultatos del recerca",
"searchresults-title": "Resultatos del recerca de \"$1\"",
"prefs-watchlist-edits": "Numero maxime de modificationes a monstrar in le observatorio:",
"prefs-watchlist-edits-max": "Numero maxime: 1000",
"prefs-watchlist-token": "Indicio pro le observatorio:",
+ "prefs-watchlist-managetokens": "Gerer indicios",
"prefs-misc": "Misc",
"prefs-resetpass": "Cambiar contrasigno",
"prefs-changeemail": "Cambiar o remover adresse de e-mail",
"recentchangesdays-max": "(non plus de $1 {{PLURAL:$1|die|dies}})",
"recentchangescount": "Numero de modificationes a monstrar per predefinition:",
"prefs-help-recentchangescount": "Isto include modificationes recente, historias de paginas, e registros.",
- "prefs-help-watchlist-token2": "Isto es le clave secrete pro le syndication web de tu observatorio.\nOmne persona qui lo cognosce pote leger tu observatorio, dunque, non divide lo.\n[[Special:ResetTokens|Clicca hic pro reinitialisar lo]].",
+ "prefs-help-tokenmanagement": "Tu pote vider e reinitialisar le clave secrete pro tu conto que pote acceder al aggregator Web de tu observatorio. Tote persona que cognosce le clave potera leger tu observatorio, dunque non divulga lo.",
"savedprefs": "Tu preferentias ha essite confirmate.",
"savedrights": "Le gruppos de usator de {{GENDER:$1|$1}} ha essite salveguardate.",
"timezonelegend": "Fuso horari:",
"rcfilters-tag-prefix-namespace-inverted": "<strong>:non</strong> $1",
"rcfilters-exclude-button-off": "Excluder le selection",
"rcfilters-exclude-button-on": "Selection excludite",
- "rcfilters-view-advanced-filters-label": "Filtros avantiate",
"rcfilters-view-tags": "Modificationes con etiquettas",
"rcfilters-view-namespaces-tooltip": "Filtrar le resultatos per spatio de nomines",
"rcfilters-view-tags-tooltip": "Filtrar le resultatos usante etiquettas de version",
"Rachmat04",
"Arifpedia",
"Uchup19",
- "Archd"
+ "Archd",
+ "Empu"
]
},
"tog-underline": "Garis bawahi pranala:",
"recentchangesdays-max": "(maksimum $1 {{PLURAL:$1|hari|hari}})",
"recentchangescount": "Standar jumlah suntingan yang ditampilkan:",
"prefs-help-recentchangescount": "Opsi ini berlaku untuk perubahan terbaru, versi terdahulu halaman, dan log.",
- "prefs-help-watchlist-token2": "Ini adalah kunci rahasia (token) ke umpan web dari daftar pantauan Anda.\nSiapa saja yang tahu akan dapat melihat daftar pantauan Anda, jadi jangan dibagikan. Jika diperlukan\n[[Special:ResetTokens|Anda dapat mengatur ulang kunci tersebut]].",
"savedprefs": "Preferensi Anda telah disimpan",
"savedrights": "Kelompok hak pengguna {{GENDER:$1|$1}} telah disimpan.",
"timezonelegend": "Zona waktu:",
"recentchanges-summary": "Temukan perubahan terbaru dalam wiki di halaman ini.<br />\n;Keterangan:(<span style=\"color:blue;\">beda</span>) perubahan, (<span style=\"color:blue;\">versi</span>) sejarah revisi, '''B''' halaman baru, '''b''' suntingan bot, '''k''' suntingan kecil, <span class=\"unpatrolled\">!</span> perubahan belum dipatroli,<br /><span style=\"color:green;\">'''(+ ''bita'')'''</span> isi konten bertambah, <span style=\"color:red;\">(- ''bita'')</span> isi konten berkurang, (← Ringkasan otomatis), (→ <span style=\"color:grey;\">Suntingan bagian</span>)",
"recentchanges-noresult": "Tidak ada perubahan dalam rentang waktu ini yang cocok dengan kriteria.",
"recentchanges-timeout": "Waktu pencarian ini telah habis. Anda mungkin ingin mencoba parameter pencarian lain.",
+ "recentchanges-network": "Selama terjadi kesalahan teknis, tidak ada hasil yang bisa dimuat. Silakan coba untuk menyegarkan kembali halaman.",
"recentchanges-feed-description": "Temukan perubahan terbaru dalam wiki di umpan ini.",
"recentchanges-label-newpage": "Suntingan ini membuat halaman baru",
"recentchanges-label-minor": "Ini adalah suntingan kecil",
"diff-multi-sameuser": "({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di uno stesso utente non {{PLURAL:$1|è mostrata|sono mostrate}})",
"diff-multi-otherusers": "({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di {{PLURAL:$2|un altro utente|$2 utenti}} non mostrate)",
"diff-multi-manyusers": "({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di oltre $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrata|mostrate}})",
+ "diff-paragraph-moved-tonew": "Il paragrafo è stato spostato. Clicca per passare alla nuova posizione.",
+ "diff-paragraph-moved-toold": "Il paragrafo è stato spostato. Clicca per passare alla vecchia posizione.",
"difference-missing-revision": "{{PLURAL:$2|Una versione|$2 versioni}} di questa differenza ($1) {{PLURAL:$2|non è stata trovata|non sono state trovate}}.\n\nQuesto si verifica solitamente seguendo un collegamento obsoleto di un diff a una pagina cancellata.\nI dettagli possono essere trovati nel [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro delle cancellazioni].",
"searchresults": "Risultati della ricerca",
"searchresults-title": "Risultati della ricerca di \"$1\"",
"prefs-watchlist-edits": "Numero massimo di modifiche da mostrare negli osservati speciali:",
"prefs-watchlist-edits-max": "Numero massimo: 1000",
"prefs-watchlist-token": "Token osservati speciali:",
+ "prefs-watchlist-managetokens": "Gestisci token",
"prefs-misc": "Varie",
"prefs-resetpass": "Cambia password",
"prefs-changeemail": "Modifica o rimuovi indirizzo di posta elettronica",
"recentchangesdays-max": "(massimo $1 {{PLURAL:$1|giorno|giorni}})",
"recentchangescount": "Numero di modifiche da mostrare per default:",
"prefs-help-recentchangescount": "Comprende ultime modifiche, cronologie e registri.",
- "prefs-help-watchlist-token2": "Questa è la chiave segreta per il feed web dei tuoi osservati speciali.\nChiunque la conosce sarà in grado di leggere i tuoi osservati speciali, per cui non condividerla. [[Special:ResetTokens|Clicca qui se hai bisogno di reimpostarla]].",
+ "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosce la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
"savedprefs": "Le preferenze sono state salvate.",
"savedrights": "I gruppi utente di {{GENDER:$1|$1}} sono stati salvati.",
"timezonelegend": "Fuso orario:",
"nosuchusershort": "「$1」という名前の利用者は存在しません。\n綴りを確認してください。",
"nouserspecified": "利用者名を指定してください。",
"login-userblocked": "この利用者はブロックされています。ログインは拒否されます。",
- "wrongpassword": "パスワードが間違っています。 \nもう一度やり直してください。",
+ "wrongpassword": "利用者名またはパスワードが間違っています。 \nもう一度やり直してください。",
"wrongpasswordempty": "パスワードを空欄にはできません。\nもう一度やり直してください。",
"passwordtooshort": "パスワードは {{PLURAL:$1|$1 文字}}以上にしてください。",
"passwordtoolong": "パスワードは {{PLURAL:$1|$1 文字}}以下にしてください。",
"recentchangesdays-max": "(最大 $1 {{PLURAL:$1|日|日間}})",
"recentchangescount": "既定で表示する件数:",
"prefs-help-recentchangescount": "この設定は最近の更新、ページの履歴、および記録に適用されます。",
- "prefs-help-watchlist-token2": "これはあなたのウォッチリスト フィードの秘密のコードです。\nこのトークンを知っている人は誰でもあなたのウォッチリストを読めてしまうため、他の人に教えないでください。\n[[Special:ResetTokens|トークンを再設定する必要がある場合はここをクリックしてください]]。",
"savedprefs": "個人設定を保存しました。",
"savedrights": "{{GENDER:$1|$1}}の利用者グループが保存されました。",
"timezonelegend": "タイムゾーン:",
"recentchangesdays-max": "(maksimum $1 {{PLURAL:$1|dina|dina}})",
"recentchangescount": "Cacahing besutan sing dituduhaké kanthi baku:",
"prefs-help-recentchangescount": "Iki klebu owah-owahan pungkasan, kaca sajarah, lan log.",
- "prefs-help-watchlist-token2": "Ini adalah kunci rahasia (token) ke web feed dari daftar pantauan Anda.\nSiapa saja yang tahu akan dapat melihat daftar pantauan Anda, jadi jangan dibagikan.\n[[Special:ResetTokens|Klik di sini jika Anda perlu menyetel ulang]].",
"savedprefs": "Prèferènsi Panjenengan wis disimpen",
"savedrights": "Golongan panganggo {{GENDER:$1|$1}} wis disimpen.",
"timezonelegend": "Zona wektu:",
"diff-multi-sameuser": "(같은 사용자의 {{PLURAL:$1|중간 판 하나|중간 판 $1개}}는 보이지 않습니다)",
"diff-multi-otherusers": "({{PLURAL:$2|다른 사용자 한 명|사용자 $2명}}의 {{PLURAL:$1|중간 판 하나|중간 판 $1개}}는 보이지 않습니다)",
"diff-multi-manyusers": "({{PLURAL:$2|사용자}} $2명 이상의 {{PLURAL:$1|중간 판 하나|중간 판 $1개}}는 보이지 않습니다)",
+ "diff-paragraph-moved-tonew": "문단이 이동되었습니다. 새로운 위치로 이동하려면 클릭하십시오.",
+ "diff-paragraph-moved-toold": "문단이 이동되었습니다. 오래된 위치로 이동하려면 클릭하십시오.",
"difference-missing-revision": "문서 비교에서 {{PLURAL:$2|하나|$2개}}의 판($1)을 찾을 수 {{PLURAL:$2|없습니다}}.\n\n이 문제는 주로 삭제된 문서를 가리키는 오래된 문서 비교 링크로 인해 발생합니다.\n자세한 내용은 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 삭제 기록]에서 확인할 수 있습니다.",
"searchresults": "검색 결과",
"searchresults-title": "\"$1\"에 대한 검색 결과",
"recentchangesdays-max": "최대 $1{{PLURAL:$1|일}}",
"recentchangescount": "기본으로 보여줄 편집 수:",
"prefs-help-recentchangescount": "이 설정은 최근 바뀜, 문서 역사와 기록에 적용됩니다.",
- "prefs-help-watchlist-token2": "내 주시문서 목록의 웹 피드의 비밀 키입니다.\n이 키를 알고 있는 사람은 내 주시문서 목록을 읽을 수 있으니 이 키를 공유하지 마세요.\n필요하다면 [[Special:ResetTokens|이 키를 재설정할 수 있습니다]].",
"savedprefs": "설정을 저장했습니다.",
"savedrights": "{{GENDER:$1|$1}}의 사용자 그룹이 저장되었습니다.",
"timezonelegend": "시간대:",
"nosuchusershort": "De Benotzernumm \"$1\" gëtt et net.\nKuckt w.e.g. op d'Schreifweis richteg ass.",
"nouserspecified": "Gitt w.e.g. e Benotzernumm un.",
"login-userblocked": "Dëse Benotzer ass gespaart. Aloggen ass net erlaabt.",
- "wrongpassword": "Dir hutt e falscht (oder kee) Passwuert aginn. Probéiert w.e.g. nach eng Kéier.",
+ "wrongpassword": "De Benotzernumm oder d'Passwuert si falsch.\nProbéiert w.e.g. nach eng Kéier.",
"wrongpasswordempty": "D'Passwuert dat Dir aginn hutt war eidel.\nProbéiert w.e.g. nach eng Kéier.",
"passwordtooshort": "Passwierder musse mindestens {{PLURAL:$1|1 Zeeche|$1 Zeeche}} laang sinn.",
"passwordtoolong": "Passwierder kënnen net méi laang wéi {{PLURAL:$1|1 Zeeche|$1 Zeeche}} sinn.",
"recentchangesdays-max": "(Maximal $1 {{PLURAL:$1|Dag|Deeg}})",
"recentchangescount": "Zuel vun den Ännerungen déi als Standard gewise ginn:",
"prefs-help-recentchangescount": "Inklusiv Rezent Ännerungen, Versiounshistoriquen a Logbicher.",
- "prefs-help-watchlist-token2": "Dëst ass de geheime Schlëssel fir de Webfeed vun Ärer Iwwerwaachungslëscht. Jiddwereen deen e kennt kann Är Iwwerwaachungslëscht liesen, dofir sollt Dir en net weider ginn. [[Special:ResetTokens|Klickt hei wann Dir en zrécksetze musst]].",
"savedprefs": "Är Astellunge goufe gespäichert.",
"savedrights": "D'Benotzergruppe vum {{GENDER:$1|$1}} goufe gespäichert.",
"timezonelegend": "Zäitzon:",
"rcfilters-savedqueries-apply-and-setdefault-label": "Standardfilter uleeën",
"rcfilters-savedqueries-cancel-label": "Ofbriechen",
"rcfilters-savedqueries-add-new-title": "Aktuell Filter-Astellunge späicheren",
- "rcfilters-savedqueries-already-saved": "Dës Filtere si scho gespäichert",
+ "rcfilters-savedqueries-already-saved": "Dës Filtere si scho gespäichert. Ännert Är Astellunge fir en neie Gespäicherte Filter unzeleeën.",
"rcfilters-restore-default-filters": "Standardfiltere restauréieren",
"rcfilters-clear-all-filters": "All Filteren eidelmaachen",
"rcfilters-show-new-changes": "Rezentst Ännerunge weisen",
"rcfilters-filterlist-feedbacklink": "Sot eis wat Dir vun dësen (neien) Filterméiglechkeeten haalt",
"rcfilters-highlightbutton-title": "Resultater ervirhiewen",
"rcfilters-highlightmenu-title": "Eng Faarf eraussichen",
+ "rcfilters-highlightmenu-help": "Sicht eng Faarf eraus fir dës Eegenschaft ervirzehiewen.",
"rcfilters-filterlist-noresults": "Keng Filtere fonnt",
"rcfilters-noresults-conflict": "Näischt fonnt well d'Sichcritère sech widderspriechen",
"rcfilters-filter-editsbyself-label": "Ännerunge vun Iech",
"recentchangesdays-max": "Ne vairāk kā $1 {{PLURAL:$1|dienas|diena|dienas}}",
"recentchangescount": "Izmaiņu skaits, kuru rāda pēc noklusējuma:",
"prefs-help-recentchangescount": "Šis parametrs attiecas uz pēdējo izmaiņu un hronoloģijas lapām, kā arī uz sistēmas žurnāliem",
- "prefs-help-watchlist-token2": "Šī ir slepena atslēga tavam uzraugāmo lapu sarakstam.\nIkvienam, kas to zinās, būs iespēja apskatīt tavu uzraugāmo lapu sarakstu, tāpēc nedalies ar to.\n[[Special:ResetTokens|Spied šeit, lai to atjaunotu]].",
"savedprefs": "Jūsu izvēles ir saglabātas.",
"timezonelegend": "Laika josla:",
"localtime": "Vietējais laiks:",
"filehist-comment": "Komentārs",
"imagelinks": "Faila lietojums",
"linkstoimage": "{{PLURAL:$1|Šajās $1 lapās ir saites|Šajā lapā ir saite|Šajās $1 lapās ir saites}} uz šo failu:",
+ "linkstoimage-more": "Uz šo failu ir saites vairāk nekā $1 {{PLURAL:$1|lapās|lapā|lapās}}.\nŠajā sarakstā ir tikai {{PLURAL:$1|pirmās $1 saistītās lapas|pirmā $1 saistītā lapa|pirmās $1 saistītās lapas}} uz šo failu.\nPieejams arī [[Special:WhatLinksHere/$2|pilns saraksts]].",
"nolinkstoimage": "Nevienā lapā nav norāžu uz šo attēlu.",
"morelinkstoimage": "Skatīt [[Special:WhatLinksHere/$1|vairāk saites]] uz šo failu.",
"linkstoimage-redirect": "$1 (faila pāradresācija) $2",
"unwatchthispage": "Pārtraukt uzraudzīšanu",
"notanarticle": "Nav satura lapa",
"notvisiblerev": "Cita lietotāja pēdējā versija ir izdzēsta",
- "watchlist-details": "(Tu uzraugi $1 {{PLURAL:$1|lapu|lapas}}, neieskaitot diskusiju lapas.)",
+ "watchlist-details": "Tu uzraugi $1 {{PLURAL:$1|lapas|lapu|lapas}} (neieskaitot diskusiju lapas).",
"wlheader-enotif": "E-pasta paziņojumi ir ieslēgti.",
"wlheader-showupdated": "Lapas, kas ir tikušas izmainītas, kopš pēdējoreiz skatījies tās, tiek rādītas <strong>trekninātā</strong> rakstā.",
"wlshowlast": "Rādīt pēdējās $1 stundas $2 dienas",
"逆襲的天邪鬼"
]
},
- "tog-underline": "鏈墊線:",
+ "tog-underline": "以底線識鏈接:",
"tog-hideminor": "隱近校",
"tog-hidepatrolled": "隱近巡",
"tog-newpageshidepatrolled": "隱新巡",
"tog-previewonfirst": "覽首修",
"tog-enotifwatchlistpages": "哨新,遣函",
"tog-enotifusertalkpages": "議新,遣函",
- "tog-enotifminoredits": "æ ¡æ\96°ï¼\8cé\81£å\87½",
+ "tog-enotifminoredits": "æ¯\8fæ\9c\89ä¿®è¨\82ï¼\8cé\9b\96é\9d\9eé\87\8dè¦\81ä¹\8b屬ï¼\8c亦é\81£é\83µ",
"tog-enotifrevealaddr": "列余址於書內",
"tog-shownumberswatching": "放哨有",
"tog-oldsig": "覽原署名:",
"tog-watchlisthideown": "不哨己文",
"tog-watchlisthidebots": "不哨僕文",
"tog-watchlisthideminor": "不哨細纂",
- "tog-watchlisthideliu": "不哨有簿",
- "tog-watchlisthideanons": "不哨無簿",
- "tog-watchlisthidepatrolled": "不哨已巡",
- "tog-watchlisthidecategorization": "隱頁類",
- "tog-ccmeonemails": "凡所遺書,請存副本。",
- "tog-diffonly": "異下無示頁",
- "tog-showhiddencats": "示隱類",
+ "tog-watchlisthideliu": "不監在簿",
+ "tog-watchlisthideanons": "不監無簿",
+ "tog-watchlisthidepatrolled": "不監既審",
+ "tog-watchlisthidecategorization": "不示類屬",
+ "tog-ccmeonemails": "凡所遺書,亦謄錄之,存於郵篋。",
+ "tog-diffonly": "方校讎時,下端無庸具示原文",
+ "tog-showhiddencats": "隱類悉示",
"tog-norollbackdiff": "轉後略異",
"tog-useeditwarning": "離而未存,示吾",
"tog-prefershttps": "入簿復用安全鏈",
"versionrequiredtext": "惠置$1媒維基,見[[Special:Version|版]]。",
"ok": "可",
"retrievedfrom": "取自\"$1\"",
- "youhavenewmessages": "有$1書至子書房也。($2)",
+ "youhavenewmessages": "{{PLURAL:$3|新接}} $1($2)。",
"youhavenewmessagesfromusers": "子有 $1 自 {{PLURAL:$3|一簿戶也|$3 簿戶也}} ($2)。",
- "youhavenewmessagesmanyusers": "子有 $1 自多簿戶 ( $2 )",
- "newmessageslinkplural": "{{PLURAL:$1|一新訊|999=新訊}}",
- "newmessagesdifflinkplural": "新易",
+ "youhavenewmessagesmanyusers": "諸士音信新來。其$1,悉存乎齋($2)。",
+ "newmessageslinkplural": "{{PLURAL:$1|書簡凡一|999=二三書簡}}",
+ "newmessagesdifflinkplural": "新{{PLURAL:$1|易}}",
"youhavenewmessagesmulti": "新訊於$1",
"editsection": "纂",
"editold": "纂",
"editingcomment": "撰$1",
"editconflict": "纂沖$1",
"explainconflict": "子纂與他人沖,上者時也,下者子也,望子合之。\n註,'''$1'''上文儲焉",
- "yourtext": "å\90ä¹\9f",
+ "yourtext": "å\90\9bæ\89\80æ\92°è¿°",
"storedversion": "時也",
"editingold": "'''\"警示\"子纂舊然。強儲之,則新易失焉。'''",
"yourdiff": "異",
"tog-watchuploads": "Sogna file anyar sing nyong unggah nang daptar sawangane nyong",
"tog-watchrollback": "Tambahna kaca sing wis tek rollback maring daftar pangawasane inyong",
"tog-minordefault": "Otomatis nandani kabeh suntingan dadi suntingan cilik",
- "tog-previewontop": "Tidokna pratayang sedurunge kotak sunting",
+ "tog-previewontop": "Tidhokna pratayang sedurunge kotak sunting",
"tog-previewonfirst": "Tidokna pratayang nang suntingan sing pertama",
"tog-enotifwatchlistpages": "Kirimna imel maring inyong angger kaca awa berkas utsing mlebu daptar pangawasanne inyong diowaih",
"tog-enotifusertalkpages": "Kirimna imel maring inyong angger kaca dhiskusine inyong owah",
"createacct-yourpasswordagain-ph": "Lebokna tembung sandhi maning",
"userlogin-remembermypassword": "Jorna ben Inyong tetep mlebu log",
"userlogin-signwithsecure": "Gunakna koneksi aman",
+ "cannotlogin-title": "Ora bisa mlebu log",
+ "cannotlogin-text": "Ora mungkin mlebu log.",
"cannotloginnow-title": "Ora teyeng mlebu siki",
+ "cannotcreateaccount-title": "Ora bisa gawé akun",
"yourdomainname": "Domain Rika:",
"password-change-forbidden": "Rika ora teyeng ngowaih tembung sandhi nang wiki kiye.",
"externaldberror": "Ana kesalahan otentikasi basis data utawa Rika ora olih nglakokna pemutakhiran maring akun eksternale Rika.",
"user-mail-no-body": "Njajal ngirim imel sing kosong urawa isine sithik thok.",
"changepassword": "Ganti tembung sandhi",
"resetpass_announce": "Kanggo ngrampungna gole mlebu log, rika kudu nglebokna tembung sandhi anyar.",
+ "resetpass_text": "<!-- Tambah teks neng kéné -->",
"resetpass_header": "Ganti tembung sandhine akun",
"oldpassword": "Tembung sandi lawas:",
"newpassword": "Tembung sandi anyar:",
"resetpass_submit": "Nata tembung sandhi lan mlebu log",
"changepassword-success": "Sandhiné Rika uwis diganti!",
"changepassword-throttled": "Rika wis kakehan gole njajal mlebu log.\nTulung ngenteni $1 sedurunge njajal maning.",
+ "botpasswords-label-create": "Gawé",
+ "botpasswords-label-update": "Nganyari",
+ "botpasswords-label-cancel": "Batalna",
+ "botpasswords-label-delete": "Busek",
"resetpass_forbidden": "Tembung sandhi ora teyeng diganti",
"resetpass-no-info": "Rika kudu mlebu log kanggo ngakses kaca kiye sacara langsung.",
"resetpass-submit-loggedin": "Ganti tembung sandhi",
"headline_tip": "Subbagian tingkat 1",
"nowiki_sample": "Lebokna teks sing ora bakal diformat nang kene",
"nowiki_tip": "Aja nganggo format wiki",
+ "image_sample": "Conto.jpg",
"image_tip": "Ngaweh berkas",
+ "media_sample": "Conto.ogg",
"media_tip": "Pranala berkas media",
"sig_tip": "Tapak astane Rika nganggo tandha wektu",
"hr_tip": "Garis horisontal",
"minoredit": "Kiye suntingan cilik",
"watchthis": "Awasi kaca kiyé",
"savearticle": "Terbitna Kaca",
+ "publishpage": "Pacak kacané",
"preview": "Pra tayang",
"showpreview": "Pra tayang",
"showdiff": "Ndeleng bedané",
"editingsection": "Nyunting $1 (bagiyan)",
"editingcomment": "Nyunting $1 (bagéyan anyar)",
"editconflict": "Konflik panyuntingan: $1",
+ "yourtext": "Teks-é rika",
"protectedpagewarning": "'''Pénget: Kaca kiye wis dikunci dadi mung panganggo sing nduwé hak aksès pangurus baé sing teyeng nyunting.'''\nEntri cathetan pungkasan disadiakna nang ngisor kanggo referensi:",
"semiprotectedpagewarning": "'''Cathetan:''' Kaca kiye lagi pinuju direksa, dadi mung panganggo kadaftar sing teyeng nyunting.\nEntri cathetan pungkasan disadiakna nang ngisor kanggo referensi:",
"templatesused": "{{PLURAL:$1|Cithakan|Cithakan}} sing dienggo nang kaca kiye:",
"rcshowhideliu": "$1 panganggo sing mlebu log",
"rcshowhideanons": "$1 panganggo anonim",
"rcshowhidepatr": "$1 suntingan sing dipatroli",
- "rcshowhidemine": "$1 suntingane inyong",
+ "rcshowhidemine": "$1 suntingané inyong",
"rclinks": "Tidokna $1 owahan pungkasan nang $2 dina pungkasan kiye",
"diff": "bédane",
"hist": "versi",
"nosuchusershort": "Нема корисник со името „$1“.\nПроверете дали правилно сте напишале.",
"nouserspecified": "Мора да наведете корисничко име.",
"login-userblocked": "Овој корисник е блокиран. Најавувањето не е дозволено.",
- "wrongpassword": "Ð\92неÑ\81овÑ\82е погÑ\80еÑ\88на лозинка. Обидете се повторно.",
+ "wrongpassword": "Ð\92неÑ\81овÑ\82е погÑ\80еÑ\88но коÑ\80иÑ\81ниÑ\87ко име или лозинка.\nОбидете се повторно.",
"wrongpasswordempty": "Внесената лозинка е празна. Обидете се повторно.",
"passwordtooshort": "Лозинката мора да има најмалку {{PLURAL:$1|1 знак|$1 знаци}}.",
"passwordtoolong": "Лозинката не треба да има повеќе од {{PLURAL:$1|1 знак|$1 знаци}}.",
"diff-multi-sameuser": "({{PLURAL:$1|Не е прикажана една меѓувремена преработка|Не се прикажани $1 меѓувремени преработки}} од истиот корисник)",
"diff-multi-otherusers": "({{PLURAL:$1|Не е прикажана една меѓувремена преработка|Не се прикажани $1 меѓувремени преработки}} од {{PLURAL:$2|еден друг корисник|$2 корисници}})",
"diff-multi-manyusers": "({{PLURAL:$1|Не е прикажана една меѓувремена преработка направена|Не се прикажани $1 меѓувремени преработки направени}} од повеќе од $2 {{PLURAL:$2|корисник|корисници}})",
+ "diff-paragraph-moved-tonew": "Пасусот е преместен. Стиснете за да прејдете на новото место.",
+ "diff-paragraph-moved-toold": "Пасусот е преместен. Стиснете за да прејдете на старото место.",
"difference-missing-revision": "Не пронајдов {{PLURAL:$2|една преработка|$2 преработки}} од оваа разлика ($1).\n\nОва обично се должи на застарена врска за разлики што води кон избришана страница.\nПовеќе подробности ќе најдете во [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дневникот на бришења].",
"searchresults": "Исход од пребарувањето",
"searchresults-title": "Исход од пребарувањето на „$1“",
"recentchangesdays-max": "(највеќе {{PLURAL:$1|еден ден|$1 дена}})",
"recentchangescount": "Број на уредувања кои ќе се прикажуваат по основно:",
"prefs-help-recentchangescount": "Подразбира скорешни промени, истории на страници и дневници.",
- "prefs-help-watchlist-token2": "Ова е тајна шифра за вашиот канализиран список на набљудувања.\nСекој што ја знае ќе може да ја чита, па затоа ви препорачуваме да не ја кажувате никому.\n[[Special:ResetTokens|Стиснете тука ако треба да зададете нова]].",
"savedprefs": "Вашите нагодувања се зачувани.",
"savedrights": "Корисничките групи на {{GENDER:$1|$1}} се зачувани.",
"timezonelegend": "Часовен појас:",
"rcfilters-savedqueries-apply-and-setdefault-label": "Создај стандарден филтер",
"rcfilters-savedqueries-cancel-label": "Откажи",
"rcfilters-savedqueries-add-new-title": "Зачувај тековни филтерски поставки",
- "rcfilters-savedqueries-already-saved": "Овие филтри се веќе зачувани",
+ "rcfilters-savedqueries-already-saved": "Овие филтри се веќе зачувани. Сменете ги поставките за да направите нов зачуван филтер.",
"rcfilters-restore-default-filters": "Поврати основни филтри",
"rcfilters-clear-all-filters": "Тргни ги сите филтри",
"rcfilters-show-new-changes": "Погл. најнови промени",
"rcfilters-filter-excluded": "ချန်လှပ်",
"rcfilters-exclude-button-off": "ရွေးချယ်ထားသည်များ ချန်လှပ်ရန်",
"rcfilters-exclude-button-on": "ရွေးချယ်ထားသည်များ ချန်လှပ်နေသည်",
- "rcfilters-view-advanced-filters-label": "အဆင့်မြင့် filter များ",
"rcfilters-view-tags": "စာတွဲမှတ်ထားသော တည်းဖြတ်မှုများ",
"rcfilters-view-namespaces-tooltip": "အမည်ညွှန်းအလိုက် ရလဒ်များ စစ်ထုတ်ရန်",
"rcfilters-view-tags-tooltip": "တည်းဖြတ်စာတွဲများ အသုံးပြု၍ ရလဒ်များ စစ်ထုတ်ရန်",
"dellogpage": "ဖျက်ထားသည်များ မှတ်တမ်း",
"dellogpagetext": "အောက်ပါတို့သည် မကြာမီက ဖျက်ထားမှုများ စာရင်း ဖြစ်သည်။",
"deletionlog": "ဖျက်ပစ်သည့်မှတ်တမ်း",
+ "reverted": "ယခင်တည်းဖြတ်မူသို့ နောက်ပြန်ပြင်ပြီးပြီ",
"deletecomment": "အကြောင်းပြချက် -",
"deleteotherreason": "အခြားသော/နောက်ထပ် အကြောင်းပြချက် -",
"deletereasonotherlist": "အခြား အကြောင်းပြချက်",
"nosuchusershort": "Det finnes ingen bruker ved navn «$1». Kontroller stavemåten.",
"nouserspecified": "Du må oppgi et brukernavn.",
"login-userblocked": "Brukeren er blokkert. Innlogging er ikke tillatt.",
- "wrongpassword": "Du har oppgitt et ugyldig passord. Prøv igjen.",
+ "wrongpassword": "Galt brukernavn eller passord oppgitt.\nPrøv igjen.",
"wrongpasswordempty": "Du oppga ikke noe passord. Prøv igjen.",
"passwordtooshort": "Passord må ha minst {{PLURAL:$1|ett tegn|$1 tegn}}.",
"passwordtoolong": "Passord kan ikke overskride {{PLURAL:$1|1 character|$1 characters}}.",
"diff-multi-sameuser": "({{PLURAL:$1|Én mellomliggende revisjon|$1 mellomliggende revisjoner}} av samme bruker vises ikke)",
"diff-multi-otherusers": "({{PLURAL:$1|En mellomliggende revisjon|$1 mellomliggende revisjoner}} av {{PLURAL:$2|en annen bruker|$2 brukere}} er ikke vist)",
"diff-multi-manyusers": "({{PLURAL:$1|Én mellomrevisjon|$1 mellomrevisjoner}} av mer enn $2 {{PLURAL:$2|bruker|brukere}} vises ikke)",
+ "diff-paragraph-moved-tonew": "Avsnittet ble flyttet. Klikk for å hoppe til den nye plasseringen.",
+ "diff-paragraph-moved-toold": "Avsnittet ble flyttet. Klikk for å hoppe til den gamle plasseringen.",
"difference-missing-revision": "{{PLURAL:$2|En revisjon|$2 revisjoner}} av denne forskjellen ($1) {{PLURAL:$2|ble|ble}} ikke funnet.\n\nDette skyldes som regel at en gammel forskjell-lenke er fulgt til en side som er slettet.\nDetaljer kan finnes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} sletteloggen].",
"searchresults": "Søkeresultater",
"searchresults-title": "Søkeresultater for «$1»",
"prefs-watchlist-edits": "Maksimalt antall redigeringer som skal vises i overvåkningslisten:",
"prefs-watchlist-edits-max": "Maksimalt antall: 1000",
"prefs-watchlist-token": "Nøkkel for overvåkningsliste",
+ "prefs-watchlist-managetokens": "Behandle nøkler",
"prefs-misc": "Diverse",
"prefs-resetpass": "Endre passord",
"prefs-changeemail": "Endre eller fjerne e-postadresse",
"recentchangesdays-max": "Maks $1 {{PLURAL:$1|dag|dager}}",
"recentchangescount": "Antall redigeringer som skal vises som standard:",
"prefs-help-recentchangescount": "Dette inkluderer nylige endringer, sidehistorikk og logger.",
- "prefs-help-watchlist-token2": "Dette er den hemmelige nøkkelen til webmatingen for din overvåkningsliste.\nEnhver som kjenner nøkkelen vil kunne lese din overvåkningsliste, så ikke vis den til andre.\n[[Special:ResetTokens|Klikk her om du trenger å nullstille nøkkelen]].",
+ "prefs-help-tokenmanagement": "Du kan se og resette den hemmelige nøkkelen for kontoen din som kan få tilgang til matingen med overvåkningslisten din. Alle som har nøkkelen vil kunne lese overvåkningslisten din, så ikke del den.",
"savedprefs": "Innstillingene ble lagret.",
"savedrights": "Brukergruppene til {{GENDER:$1|$1}} har blitt lagret.",
"timezonelegend": "Tidssone:",
"rcfilters-savedqueries-apply-and-setdefault-label": "Opprett standardfilter",
"rcfilters-savedqueries-cancel-label": "Avbryt",
"rcfilters-savedqueries-add-new-title": "Lagre de gjeldende filterinnstillingene",
- "rcfilters-savedqueries-already-saved": "Disse filtrene er allerede lagret",
+ "rcfilters-savedqueries-already-saved": "Disse filtrene er allerede lagret. Endre innstillingene dine for å opprette et nytt lagret filter.",
"rcfilters-restore-default-filters": "Gjenopprett standardfiltre",
"rcfilters-clear-all-filters": "Nullstill alle filtre",
"rcfilters-show-new-changes": "Vis de nyeste endringene",
"diff-multi-sameuser": "({{PLURAL:$1|Een tussenliggende versie|$1 tussenliggende versies}} door dezelfde gebruiker niet weergegeven)",
"diff-multi-otherusers": "({{PLURAL:$1|Een tussenliggende versie|$1 tussenliggende versies}} door {{PLURAL:$2|een andere gebruiker|$2 gebruikers}} niet weergegeven)",
"diff-multi-manyusers": "($1 tussenliggende {{PLURAL:$1|versie|versies}} door meer dan $2 {{PLURAL:$2|gebruiker|gebruikers}} worden niet weergegeven)",
+ "diff-paragraph-moved-tonew": "Deze paragraaf is verplaatst. Klik om naar de nieuwe locatie te springen.",
+ "diff-paragraph-moved-toold": "Deze paragraaf is verplaatst. Klik om naar de oude locatie te springen.",
"difference-missing-revision": "{{PLURAL:$2|Eén versie|$2 versies}} van deze verschillen ($1) {{PLURAL:$2|is|zijn}} niet aangetroffen.\n\nDit wordt meestal veroorzaakt door het volgen van een verouderde koppeling verschillen voor een pagina die is verwijderd.\nMeer gegevens zijn mogelijk te vinden in het [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} verwijderingslogboek].",
"searchresults": "Zoekresultaten",
"searchresults-title": "Zoekresultaten voor \"$1\"",
"prefs-watchlist-edits": "Maximaal aantal bewerkingen in de volglijst:",
"prefs-watchlist-edits-max": "Maximale aantal: 1000",
"prefs-watchlist-token": "Volglijstsleutel:",
+ "prefs-watchlist-managetokens": "Token beheren",
"prefs-misc": "Diversen",
"prefs-resetpass": "Wachtwoord wijzigen",
"prefs-changeemail": "E-mailadres wijzigen of verwijderen",
"recentchangesdays-max": "(maximaal $1 {{PLURAL:$1|dag|dagen}})",
"recentchangescount": "Standaard aantal weer te geven bewerkingen:",
"prefs-help-recentchangescount": "Dit geldt voor recente wijzigingen, paginageschiedenis en logboekpagina's.",
- "prefs-help-watchlist-token2": "Dit is de geheime sleutel voor de webfeed van uw volglijst.\nIedereen die het token kent, kan uw volglijst bekijken, dus deel dit token niet.\nU kunt de [[Special:ResetTokens|tokens opnieuw instellen]] als u dat wilt.",
+ "prefs-help-tokenmanagement": "U kunt uw geheime sleutel voor uw account bekijken en resetten. De geheime sleutel biedt toegang tot de webfeed van uw volglijst. Iedereen die het token kent, kan uw volglijst bekijken, dus deel dit token niet.",
"savedprefs": "Uw voorkeuren zijn opgeslagen.",
"savedrights": "De gebruikergroepen van {{GENDER:$1|$1}} zijn opgeslagen.",
"timezonelegend": "Tijdzone:",
"recentchangesdays-max": "(maksymalnie $1 {{PLURAL:$1|dzień|dni}})",
"recentchangescount": "Domyślna liczba wyświetlanych edycji:",
"prefs-help-recentchangescount": "Uwzględnia ostatnie zmiany, historię stron i rejestry.",
- "prefs-help-watchlist-token2": "To jest tajny klucz umożliwiający dostęp do kanału internetowego zmian w obserwowanych przez ciebie stronach.\nKażdy, kto go zna, będzie mógł je zobaczyć, więc zachowaj go dla siebie.\n[[Special:ResetTokens|Kliknij tu, jeśli chcesz go zresetować]].",
"savedprefs": "Twoje preferencje zostały zapisane.",
"savedrights": "Zapisano grupy {{GENDER:$1|użytkownika $1|użytkowniczki $1}}.",
"timezonelegend": "Strefa czasowa:",
"diff-multi-sameuser": "({{PLURAL:$1|Uma revisão intermediária|$1 revisões intermediárias}} pelo mesmo usuário não {{PLURAL:$1|está sendo mostrada|estão sendo mostradas}})",
"diff-multi-otherusers": "({{PLURAL:$1|Uma revisão intermediária por {{PLURAL:$2|um outro usuário|$2 usuários}} não está sendo mostrada|$1 revisões intermediárias por {{PLURAL:$2|um outro usuário|$2 usuários}} não estão sendo mostradas}})",
"diff-multi-manyusers": "({{PLURAL:$1|Uma edição intermediária|$1 edições intermediárias}} de mais de {{PLURAL:$2|um usuário|$2 usuários}} não {{PLURAL:$1|está sendo mostrada|estão sendo mostradas}})",
+ "diff-paragraph-moved-tonew": "O parágrafo foi movido. Clique para saltar para a nova posição.",
+ "diff-paragraph-moved-toold": "O parágrafo foi movido. Clique para saltar para a posição anterior.",
"difference-missing-revision": "{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.\n\nIsto é geralmente causado por seguir um link de histórico desatualizado para uma página que foi eliminada.\nOs detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de eliminação].",
"searchresults": "Resultados da pesquisa",
"searchresults-title": "Resultados da pesquisa por \"$1\"",
"prefs-watchlist-edits": "Número máximo de alterações para mostrar na lista de observação:",
"prefs-watchlist-edits-max": "Número máximo: 1000",
"prefs-watchlist-token": "Senha para a lista de páginas vigiadas:",
+ "prefs-watchlist-managetokens": "Gerenciar chaves",
"prefs-misc": "Diversos",
"prefs-resetpass": "Alterar senha",
"prefs-changeemail": "Alterar ou remover endereço de email",
"recentchangesdays-max": "(máximo: $1 {{PLURAL:$1|dia|dias}})",
"recentchangescount": "Número de edições a serem exibidas por padrão:",
"prefs-help-recentchangescount": "Isto inclui mudanças recentes, histórico de páginas e registros.",
- "prefs-help-watchlist-token2": "Esta é a senha secreta para o feed da Web com sua lista de tokens vigiados.\nQualquer pessoa que descobrir esta senha será capaz de ler sua lista, então não a compartilhe.\n[[Special:ResetTokens|Clique aqui para redefini-la]].",
+ "prefs-help-tokenmanagement": "Você pode ver e redefinir a chave secreta para sua conta que pode acessar o feed da Web da sua lista de vigilância. Qualquer pessoa que conheça a chave poderá ler sua lista de observação, então não compartilhe.",
"savedprefs": "As suas preferências foram salvas.",
"savedrights": "Os grupos {{GENDER:$1|do usuário|da usuária}} $1 foram gravados.",
"timezonelegend": "Fuso horário:",
"rcfilters-filterlist-title": "Filtros",
"rcfilters-filterlist-whatsthis": "Como funcionam estes?",
"rcfilters-filterlist-feedbacklink": "Diga-nos o que você pensa sobre estas (novas) ferramentas de filtragem",
- "rcfilters-highlightbutton-title": "Realçar os resultados",
+ "rcfilters-highlightbutton-title": "Destacar resultados",
"rcfilters-highlightmenu-title": "Selecione uma cor",
"rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
"rcfilters-filterlist-noresults": "Nenhum filtro encontrado",
"rcfilters-filtergroup-automated": "Contribuições automatizadas",
"rcfilters-filter-bots-label": "Robô",
"rcfilters-filter-bots-description": "Edições feitas por ferramentas automatizadas.",
- "rcfilters-filter-humans-label": "Humano (não bot)",
+ "rcfilters-filter-humans-label": "Humano (não robô)",
"rcfilters-filter-humans-description": "Edições feitas por editores humanos.",
"rcfilters-filtergroup-reviewstatus": "Estado da revisão",
"rcfilters-filter-patrolled-label": "Patrulhado",
"delete-hook-aborted": "A eliminação foi cancelada por um \"hook\".\nNão foi dada nenhuma explicação.",
"no-null-revision": "Não foi possível criar uma nova revisão nula para a página \"$1\"",
"badtitle": "Título inválido",
- "badtitletext": "O título de página solicitado era inválido, vazio, ou um link interlínguas ou interwikis incorrecto.\nTalvez contenha um ou mais caracteres que não podem ser usados em títulos.",
- "title-invalid-empty": "O título da página solicitada está vazio ou contém apenas o nome de um domínio.",
- "title-invalid-utf8": "O título da página solicitada contém uma sequência UTF-8 inválida.",
- "title-invalid-interwiki": "O título da página solicitada contém uma ligação interlíngua que não pode ser utilizada em títulos.",
- "title-invalid-talk-namespace": "O título da página solicitada refere-se a uma página de discussão que não existe.",
- "title-invalid-characters": "O título da página solicitada contém carateres inválidos: \"$1\".",
- "title-invalid-relative": "O título contém um caminho relativo. Os títulos relativos (./, ../) são inválidos porque estarão inacessíveis muitas vezes ao serem carregados pelo navegador do utilizador.",
- "title-invalid-magic-tilde": "O título da página solicitada contém uma sequência de tis inválida (<nowiki>~~~</nowiki>).",
- "title-invalid-too-long": "O título da página solicitada é demasiado longo. Não deverá ser maior que $1 {{PLURAL:$1|byte|bytes}} na codificação UTF-8.",
- "title-invalid-leading-colon": "O título da página solicitada contém um erro de pontuação (:) no início.",
+ "badtitletext": "O título de página solicitado era inválido, estava vazio, ou era uma hiperligação interlínguas ou interwikis incorreta.\nTalvez contenha um ou mais caracteres que não podem ser usados em títulos.",
+ "title-invalid-empty": "O título de página solicitado está vazio ou contém apenas o nome de um domínio.",
+ "title-invalid-utf8": "O título de página solicitado contém uma sequência UTF-8 inválida.",
+ "title-invalid-interwiki": "O título de página solicitado contém uma ligação interwikis que não pode ser utilizada em títulos.",
+ "title-invalid-talk-namespace": "O título de página solicitado refere-se a uma página de discussão que não pode existir.",
+ "title-invalid-characters": "O título de página solicitado contém carateres inválidos: \"$1\".",
+ "title-invalid-relative": "O título contém um caminho relativo. Os títulos relativos (./, ../) são inválidos porque normalmente são inacessíveis quando tratados pelo navegador do utilizador.",
+ "title-invalid-magic-tilde": "O título de página solicitado contém uma sequência de tis inválida (<nowiki>~~~</nowiki>).",
+ "title-invalid-too-long": "O título de página solicitado é demasiado longo. Não pode exceder $1 {{PLURAL:$1|byte|bytes}} em codificação UTF-8.",
+ "title-invalid-leading-colon": "O título de página solicitado contém um sinal de dois pontos (:) inválido no início.",
"perfcached": "Os seguintes dados encontram-se armazenados na ''cache'' e podem não estar atualizados. {{PLURAL:$1|Está disponível na ''cache'' um máximo de um resultado|Estão disponíveis na ''cache'' um máximo de $1 resultados}}.",
"perfcachedts": "Os seguintes dados encontram-se armazenados na ''cache'' e foram atualizados pela última vez a $1. {{PLURAL:$4|Está disponível na ''cache'' um máximo de um resultado|Estão disponíveis na ''cache'' um máximo de $4 resultados}}.",
"querypage-no-updates": "As atualizações estão presentemente desativadas para esta página.\nPor enquanto, os dados aqui presentes não poderão ser atualizados.",
"nosuchusershort": "Não existe nenhum utilizador com o nome \"$1\".\nVerifique o nome que introduziu.",
"nouserspecified": "Tem de especificar um nome de utilizador.",
"login-userblocked": "Este utilizador está bloqueado. Não é permitido o acesso.",
- "wrongpassword": "A palavra-passe que introduziu é inválida. Tente novamente, por favor.",
+ "wrongpassword": "O nome de utilizador ou a palavra-passe inseridos estão incorretos.\nTente novamente, por favor.",
"wrongpasswordempty": "A palavra-passe não foi introduzida. \nIntroduza-a, por favor.",
"passwordtooshort": "A palavra-passe deve ter no mínimo $1 {{PLURAL:$1|carácter|caracteres}}.",
"passwordtoolong": "A palavra-passe não pode exceder $1 {{PLURAL:$1|carácter|caracteres}}.",
"sectioneditnotsupported-title": "Edição de secções não suportada",
"sectioneditnotsupported-text": "A edição de secções não é suportada nesta página.",
"permissionserrors": "Erro de permissão",
- "permissionserrorstext": "Não possui permissão para fazer isso, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
+ "permissionserrorstext": "Não tem permissão para fazer isso, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
"permissionserrorstext-withaction": "Não tem permissão para $2, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
"contentmodelediterror": "Não pode editar esta revisão porque o modelo de conteúdo é <code>$1</code>, que é diferente do modelo atual da página <code>$2</code>.",
"recreate-moveddeleted-warn": "<strong>Aviso: Está a recriar uma página anteriormente eliminada.</strong>\n\nVerifique se é apropriado continuar a editar esta página.\nPara sua conveniência, é apresentado abaixo o registo de eliminação e movimentação da página:",
"diff-multi-sameuser": "(Há {{PLURAL:$1|uma edição intermédia do mesmo utilizador que não está a ser apresentada|$1 edições intermédias do mesmo utilizador que não estão a ser apresentadas}})",
"diff-multi-otherusers": "(Há {{PLURAL:$1|uma revisão intermédia|$1 revisões intermédias}} de {{PLURAL:$2|outro utilizador|$2 utilizadores}} que não {{PLURAL:$1|está a ser apresentada|estão a ser apresentadas}})",
"diff-multi-manyusers": "({{PLURAL:$1|Uma edição intermédia|$1 edições intermédias}} de mais de {{PLURAL:$2|um utilizador|$2 utilizadores}} não {{PLURAL:$1|apresentada|apresentadas}})",
+ "diff-paragraph-moved-tonew": "O parágrafo foi movido. Clique para saltar para a nova posição.",
+ "diff-paragraph-moved-toold": "O parágrafo foi movido. Clique para saltar para a posição anterior.",
"difference-missing-revision": "{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.\n\nIsto é geralmente causado por seguir uma ligação de histórico desatualizada para uma página que foi eliminada.\nOs detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminação].",
"searchresults": "Resultados da pesquisa",
"searchresults-title": "Resultados da pesquisa de \"$1\"",
"prefs-watchlist-edits": "Número máximo de edições a mostrar na lista de vigiadas:",
"prefs-watchlist-edits-max": "Máximo: 1000",
"prefs-watchlist-token": "Chave secreta da lista de páginas vigiadas:",
+ "prefs-watchlist-managetokens": "Gerir chaves",
"prefs-misc": "Diversos",
"prefs-resetpass": "Alterar palavra-passe",
"prefs-changeemail": "Alterar ou remover correio eletrónico",
"recentchangesdays-max": "Máximo: $1 {{PLURAL:$1|dia|dias}}",
"recentchangescount": "Número de edições a apresentar por omissão:",
"prefs-help-recentchangescount": "Inclui mudanças recentes, histórico de páginas e registos.",
- "prefs-help-watchlist-token2": "Esta é a chave secreta para o ''feed'' RSS da sua lista de páginas vigiadas.\nQualquer pessoa que conheça a chave será capaz de ler a sua lista de páginas vigiadas, por isso não a divulgue.\n[[Special:ResetTokens|Clique aqui para redefini-la]].",
+ "prefs-help-tokenmanagement": "Pode ver e repor a chave secreta da sua conta que permite aceder ao feed da sua lista de páginas vigiadas. Qualquer pessoa que conheça a chave será capaz de ler a sua lista de páginas vigiadas, por isso não a partilhe.",
"savedprefs": "As suas preferências foram gravadas.",
"savedrights": "Os grupos {{GENDER:$1|do utilizador|da utilizadora}} $1 foram gravados.",
"timezonelegend": "Fuso horário:",
"rcfilters-savedqueries-apply-and-setdefault-label": "Criar filtro padrão",
"rcfilters-savedqueries-cancel-label": "Cancelar",
"rcfilters-savedqueries-add-new-title": "Gravar as configurações de filtros atuais",
- "rcfilters-savedqueries-already-saved": "Estes filtros já foram gravados",
+ "rcfilters-savedqueries-already-saved": "Estes filtros já foram gravados. Altera as suas configurações para criar um novo filtro gravado.",
"rcfilters-restore-default-filters": "Restaurar os filtros padrão",
"rcfilters-clear-all-filters": "Limpar todos os filtros",
"rcfilters-show-new-changes": "Mostrar as mudanças mais recentes",
"upload-dialog-title": "Carregar ficheiro",
"upload-dialog-button-cancel": "Cancelar",
"upload-dialog-button-back": "Voltar",
- "upload-dialog-button-done": "Feito",
+ "upload-dialog-button-done": "Concluído",
"upload-dialog-button-save": "Gravar",
"upload-dialog-button-upload": "Carregar",
"upload-form-label-infoform-title": "Detalhes",
"upload-form-label-own-work-message-generic-local": "Confirmo que estou a carregar este ficheiro segundo as condições de serviço e política de licenças da wiki {{SITENAME}}.",
"upload-form-label-not-own-work-message-generic-local": "Se não pode carregar este ficheiro de acordo com as normas da wiki {{SITENAME}}, por favor feche esta janela e tente outro método.",
"upload-form-label-not-own-work-local-generic-local": "Poderá querer experimentar [[Special:Upload|a página padrão de carregamento]].",
- "upload-form-label-own-work-message-generic-foreign": "Entendo que estou a carregar este ficheiro em um repositório partilhado. Confirmo que estou a fazê-lo cumprindo com os termos de serviço e com as políticas de licenciamento.",
- "upload-form-label-not-own-work-message-generic-foreign": "Se não é capaz de carregar este ficheiro sob as políticas do repositório partilhado, por favor feche esta janela e tente outro método.",
- "upload-form-label-not-own-work-local-generic-foreign": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento na wiki {{SITENAME}}]], se este ficheiro puder ser carregado de acordo com as normas da wiki.",
+ "upload-form-label-own-work-message-generic-foreign": "Compreendo que estou a carregar este ficheiro num repositório partilhado. Confirmo que estou a fazê-lo cumprindo as respetivas condições de serviço e normas de licenciamento.",
+ "upload-form-label-not-own-work-message-generic-foreign": "Se não pode carregar este ficheiro cumprindo as normas do repositório partilhado, feche esta janela e tente outro método, por favor.",
+ "upload-form-label-not-own-work-local-generic-foreign": "Também pode tentar usar [[Special:Upload|a página de carregamento da wiki {{SITENAME}}]], se este ficheiro puder ser carregado lá de acordo com as respetivas normas.",
"backend-fail-stream": "Não foi possível transmitir o ficheiro \"$1\".",
"backend-fail-backup": "Não foi possível fazer cópia de segurança do ficheiro \"$1\".",
"backend-fail-notexists": "O ficheiro $1 não existe.",
- "backend-fail-hashes": "Não foi possível obter os hashes do ficheiro para comparação.",
+ "backend-fail-hashes": "Não foi possível obter os resumos criptográficos dos ficheiros para comparação.",
"backend-fail-notsame": "Já existe um ficheiro não idêntico em \"$1\" .",
"backend-fail-invalidpath": "\"$1\" não é um caminho de armazenamento válido.",
"backend-fail-delete": "Não foi possível eliminar o ficheiro \"$1\".",
- "backend-fail-describe": "Não foi possível mudar metadados para o ficheiro \"$1\".",
+ "backend-fail-describe": "Não foi possível alterar os metadados do ficheiro \"$1\".",
"backend-fail-alreadyexists": "O ficheiro \"$1\" já existe.",
"backend-fail-store": "Não foi possível armazenar o ficheiro \"$1\" em \"$2\".",
"backend-fail-copy": "Não foi possível copiar o ficheiro \"$1\" para \"$2\".",
"img-auth-nologinnWL": "Não tem a sessão iniciada e o ficheiro \"$1\" não está na lista branca.",
"img-auth-nofile": "O ficheiro \"$1\" não existe.",
"img-auth-isdir": "Está a tentar aceder ao diretório \"$1\".\nSó é permitido o acesso a ficheiros.",
- "img-auth-streaming": "A fazer a transmissão de \"$1\".",
+ "img-auth-streaming": "A trasmitir \"$1\".",
"img-auth-public": "A função do img_auth.php é produzir ficheiros a partir de uma wiki privada.\nEsta wiki está configurada como uma wiki pública.\nPara optimizar a segurança, o img_auth.php está impossibilitado de executar.",
"img-auth-noread": "O utilizador não tem acesso de leitura ao ficheiro \"$1\".",
"http-invalid-url": "URL inválido: $1",
"doubleredirects": "Redirecionamentos duplos",
"doubleredirectstext": "Esta página lista todas as páginas que redirecionam para outras páginas de redirecionamento.\nCada linha contém ligações para o primeiro e segundo redirecionamentos, bem como o destino do segundo redirecionamento, geralmente contendo a verdadeira página de destino, que devia ser o destino do primeiro redirecionamento.\n<del>Entradas cortadas</del> já foram solucionadas.",
"double-redirect-fixed-move": "[[$1]] foi movida.\nEla foi atualizada automaticamente e agora redireciona para [[$2]].",
- "double-redirect-fixed-maintenance": "A corrigir automaticamente o redirecionamento duplo de [[$1]] para [[$2]], em um trabalho de manutenção.",
+ "double-redirect-fixed-maintenance": "A corrigir automaticamente o redirecionamento duplo de [[$1]] para [[$2]] num processo de manutenção.",
"double-redirect-fixer": "Corretor de redirecionamentos",
"brokenredirects": "Redirecionamentos quebrados",
"brokenredirectstext": "Os seguintes redirecionamentos contêm ligações para páginas inexistentes:",
"import-invalid-interwiki": "Não é possível importar da wiki especificada.",
"import-error-edit": "A página \"$1\" não foi importada porque não tem permissão para editá-la.",
"import-error-create": "A página \"$1\" não foi importada porque não tem permissão para criá-la.",
- "import-error-interwiki": "A página \"$1\" não pode ser importada pois o seu nome está reservado para um ligação externa (interlíngua).",
- "import-error-special": "A página \"$1\" não pode ser importada porque pertence a um domínio especial que não permite páginas.",
- "import-error-invalid": "A página \"$1\" não pode ser importada porque o seu nome é inválido nesta wiki.",
+ "import-error-interwiki": "A página \"$1\" não foi importada porque o nome dela está reservado para hiperligações externas (interwikis).",
+ "import-error-special": "A página \"$1\" não foi importada porque pertence a um espaço nominal especial que não permite páginas.",
+ "import-error-invalid": "A página \"$1\" não foi importada porque o nome para o qual seria importada é inválido nesta wiki.",
"import-error-unserialize": "Não foi possível anular a seriação da revisão $2 da página \"$1\". Foi reportado que a revisão usava o modelo de conteúdo $3, seriado como $4.",
"import-error-bad-location": "A revisão $2, que usa o modelo de conteúdo $3, não pode ser gravada em \"$1\" nesta wiki, porque o modelo não é suportado nessa página.",
"import-options-wrong": "{{PLURAL:$2|Opção errada|Opções erradas}}: <nowiki>$1</nowiki>",
- "import-rootpage-invalid": "A raiz da página dada é um título inválido.",
+ "import-rootpage-invalid": "A página de raiz fornecida é um título inválido.",
"import-rootpage-nosubpage": "O domínio \"$1\" da página de raiz não permite subpáginas.",
"importlogpage": "Registo de importações",
"importlogpagetext": "Importações administrativas de páginas com a preservação do histórico de edição de outras wikis.",
"tags-apply-blocked": "Não pode aplicar etiquetas de modificação nas suas alterações enquanto estiver {{GENDER:$1|bloqueado|bloqueada}}.",
"tags-apply-not-allowed-one": "A etiqueta \"$1\" não pode ser aplicada manualmente.",
"tags-apply-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta não pode ser aplicada|As seguintes etiquetas não podem ser aplicadas}} manualmente: $1",
- "tags-update-no-permission": "Não possui privilégios para adicionar ou remover etiquetas de revisões individuais ou entradas de registo.",
+ "tags-update-no-permission": "Não tem privilégios para adicionar ou remover etiquetas de revisões individuais ou entradas de registo.",
"tags-update-blocked": "Não pode adicionar ou remover etiquetas de modificação enquanto estiver {{GENDER:$1|bloqueado|bloqueada}}.",
"tags-update-add-not-allowed-one": "A etiqueta \"$1\" não pode ser adicionada manualmente.",
"tags-update-add-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta não pode ser adicionada|As seguintes etiquetas não podem ser adicionadas}} manualmente: $1",
"default-skin-not-found-no-skins": "O tema padrão da sua wiki definido em <code dir=\"ltr\">$wgDefaultSkin</code>, <code>$1</code>, não está disponível.\n\nNão tem nenhum tema instalado.\n\n; Se acabou de instalar ou atualizar o MediaWiki:\n: Provavelmente instalou-o a partir do git, ou diretamente do código fonte usando outro método. O comportamento é o esperado. O MediaWiki 1.24 e versões mais recentes não incluem qualquer tema no repositório principal. Tente instalar temas a partir do [https://www.mediawiki.org/wiki/Category:All_skins diretório de temas da mediawiki.org], assim:\n:* Descarregue o [https://www.mediawiki.org/wiki/Download tarball de instalação], que contém vários temas e extensões. Pode copiar o diretório <code>skins/</code> nele incluído.\n:* Descarregue tarballs de temas individuais, da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Use o Git para descarregar temas].\n: Se é programador(a) do MediaWiki, isto não deverá interferir com o seu repositório git. Consulte [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Configuração de Temas] para saber como ativar temas e escolher o tema padrão.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (ativado)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>desativado</strong>)",
- "mediastatistics": "Estatísticas multimédia",
+ "mediastatistics": "Estatísticas de multimédia",
"mediastatistics-summary": "Estatísticas sobre os tipos de ficheiro carregados. Inclui apenas a versão mais recente de cada ficheiro. Versões antigas ou eliminadas não estão incluídas.",
"mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
"mediastatistics-bytespertype": "Tamanho total dos ficheiros desta secção: {{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%).",
"revid": "revisão $1",
"pageid": "identificador de página $1",
"rawhtml-notallowed": "As etiquetas <html> não podem ser utilizadas fora de páginas normais.",
- "gotointerwiki": "A sair de {{SITENAME}}",
+ "gotointerwiki": "A sair da wiki {{SITENAME}}",
"gotointerwiki-invalid": "O título especificado é inválido.",
"gotointerwiki-external": "Está prestes a sair da wiki {{SITENAME}} para visitar [[$2]], que é um site externo.\n\n'''[$1 Continuar para $1]'''",
- "undelete-cantedit": "Não pode restaurar esta página, porque não tem privilégios para editar esta página.",
- "undelete-cantcreate": "Não pode restaurar esta página, porque não existe nenhuma página com este nome e não tem privilégios para criar esta página.",
+ "undelete-cantedit": "Não pode restaurar esta página porque não tem privilégios para a editar.",
+ "undelete-cantcreate": "Não pode restaurar esta página porque não existe nenhuma página com este nome e não tem privilégios para criar esta página.",
"pagedata-title": "Dados de página",
"pagedata-text": "Esta página fornece uma interface de dados para páginas. Forneça o título da página no URL, usando a sintaxe de subpáginas, por favor.\n* Aplica-se a negociação de conteúdo com base no cabeçalho Accept do seu cliente. Isto significa que os dados da página serão fornecidos no formato preferido do seu cliente.",
"pagedata-not-acceptable": "Não foi encontrado nenhum formato correspondente. Tipos MIME suportados: $1",
"diff-multi-sameuser": "This message appears in the revision history of a page when comparing two versions which aren't consecutive, and the intermediate revisions were all created by the same user as the new revision.\n\nParameters:\n* $1 - the number of revisions\n{{Related|Diff-multi}}",
"diff-multi-otherusers": "This message appears in the revision history of a page when comparing two versions which aren't consecutive, and at least one of the intermediate revisions was created by a user other than the user who created the new revision.\n\nParameters:\n* $1 - the number of revisions\n* $2 - the number of distinct other users who made those revisions\n{{Related|Diff-multi}}",
"diff-multi-manyusers": "This message appears in the revision history of a page when comparing two versions which aren't consecutive, and the intermediate revisions have been edited by more than 100 users.\n\nParameters:\n* $1 - the number of revisions, will always be 101 or more\n* $2 - the number of users that were found, which was limited at 100\n{{Related|Diff-multi}}",
+ "diff-paragraph-moved-tonew": "Explaining title tag for the indicating symbols when a paragraph was moved hinting to the new location in the Diff view.",
+ "diff-paragraph-moved-toold": "Explaining title tag for the indicating symbols when a paragraph was moved hinting to the old location in the Diff view.",
"difference-missing-revision": "Text displayed when the requested revision does not exist using a diff link.\n\nExample: [{{canonicalurl:Project:News|diff=426850&oldid=99999999}} Diff with invalid revision#]\n\nParameters:\n* $1 - the list of missing revisions IDs\n* $2 - the number of items in $1 (one or two)",
"search-summary": "{{doc-specialpagesummary|search}}",
"searchresults": "This is the title of the page that contains the results of a search.\n\n{{Identical|Search results}}",
"prefs-watchlist-edits": "Used in [[Special:Preferences]], tab \"Watchlist\".",
"prefs-watchlist-edits-max": "Shown as hint in [[Special:Preferences]], tab \"Watchlist\"",
"prefs-watchlist-token": "Used in [[Special:Preferences]], tab Watchlist.",
+ "prefs-watchlist-managetokens": "Label for the button to see and reset the user's private tokens",
"prefs-misc": "Tab used on the [[Special:Preferences|user preferences]] special page.",
"prefs-resetpass": "Button on user data tab in user preferences. When you click the button you go to the special page [[Special:ResetPass]].\n\n{{Identical|Change password}}",
"prefs-changeemail": "Link on [[Special:Preferences]] to [[Special:ChangeEmail]]. [[Special:ChangeEmail]] also allows removing email address. \n\nSee also:\n* {{msg-mw|prefs-help-email-required|help}}\n* {{msg-mw|prefs-help-email|help}}\n* {{msg-mw|prefs-help-email-others|help}}\n* {{msg-mw|prefs-setemail|link title}}",
"recentchangesdays-max": "Shown as hint in [[Special:Preferences]], tab \"Recent changes\". Parameters:\n* $1 - number of days\nSee also:\n* {{msg-mw|Prefs-watchlist-days-max}}",
"recentchangescount": "Used in [[Special:Preferences]], tab \"Recent changes\".",
"prefs-help-recentchangescount": "Used in [[Special:Preferences]], tab \"Recent changes\".",
- "prefs-help-watchlist-token2": "Used in [[Special:Preferences]], tab Watchlist. (Formerly in {{msg-mw|prefs-help-watchlist-token}}.)",
+ "prefs-help-tokenmanagement": "Used in [[Special:Preferences]], Watchlist tab.",
"savedprefs": "This message appears after saving changes to your user preferences.",
"savedrights": "This message appears after saving the user groups on [[Special:UserRights]].\n* $1 - The user name of the user which groups was saved.",
"timezonelegend": "{{Identical|Time zone}}",
"variantname-sr-ec": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-ec</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-cyrl</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
"variantname-sr-el": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-el</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-latn</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
"variantname-sr": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
- "variantname-kk-kz": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk-tr": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk-cn": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk-cyrl": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk-latn": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk-arab": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-kk": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-ku-arab": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-ku-latn": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
- "variantname-ku": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
+ "variantname-kk-kz": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk-tr": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk-cn": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk-cyrl": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk-latn": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk-arab": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-kk": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-ku-arab": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-ku-latn": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-ku": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
"variantname-tg-cyrl": "{{optional}}",
"variantname-tg-latn": "{{optional}}",
"variantname-tg": "{{optional}}",
"variantname-uz": "{{optional}}",
"variantname-uz-latn": "{{optional}}",
"variantname-uz-cyrl": "{{optional}}",
+ "variantname-crh": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-crh-latn": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
+ "variantname-crh-cyrl": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
"metadata": "The title of a section on an image description page, with information and data about the image. For example of message in use see [[commons:File:Titan-crystal_bar.JPG|Commons]].\n{{Identical|Metadata}}",
"metadata-help": "This message is followed by a table with metadata.",
"metadata-expand": "On an image description page, there is mostly a table containing data (metadata) about the image. The most important data are shown, but if you click on this link, you can see more data and information. For the link to hide back the less important data, see {{msg-mw|Metadata-collapse}}.",
"recentchangesdays-max": "(massime $1 {{PLURAL:$1|sciurne|sciurne}})",
"recentchangescount": "Numere de cangiaminde da fà vedè pe default:",
"prefs-help-recentchangescount": "Quiste 'nglude le urteme cangiaminde, le storie de le pàggene e le archivije.",
- "prefs-help-watchlist-token2": "Queste jè 'a chiave segrete a le feed d'u web de l'elenghe de le pàggene condrollate tune.\nCengate vò ccu canosce ce pò leggere l'elenghe de le pàggene condrollate tune, accussì non g'ù pò condividere.\n[[Special:ResetTokens|Cazze aqquà ce tìne abbesogne de azzerarle]].",
"savedprefs": "Le preferenze tue onne state aggiornete.",
"savedrights": "Le gruppe utinde de {{GENDER:$1$1}} onne state reggistrate.",
"timezonelegend": "Orarie d'a zone:",
"recentchangesdays-max": "(не более $1 {{PLURAL:$1|дня|дней}})",
"recentchangescount": "Количество правок, отображаемое по умолчанию:",
"prefs-help-recentchangescount": "Включает свежие правки, истории страниц, журналы.",
- "prefs-help-watchlist-token2": "Это секретный ключ для веб-канала вашего списка наблюдений.\nЛюбой, кто знает его, сможет читать ваш список наблюдения, поэтому не сообщайте его другим. [[Special:ResetTokens|Нажмите здесь, если вам нужно сбросить его]].",
"savedprefs": "Настройки сохранены.",
"savedrights": "Группы {{GENDER:$1|участника|участницы}} $1 были сохранены.",
"timezonelegend": "Часовой пояс:",
"category-file-count-limited": "Latar reaḱ {{PLURAL:$1 rẽt rẽtko}} noa rokom sokomre menaḱa.",
"listingcontinuesabbrev": "Calaḱa",
"index-category": "Unuduḱ sakam ko do bạnuḱa",
- "noindex-category": "Unuduḱ sakamkodo bạnuḱa",
+ "noindex-category": "ᱩᱱᱩᱫᱩᱜ ᱵᱟᱹᱱᱩᱜ-ᱟᱱ ᱥᱟᱦᱴᱟᱠᱚ",
"broken-file-category": "Baṅ kạmi daṛeaḱ chubi joṛao soho sakamko",
"about": "Lạgitte, Lạgti",
"article": "Menaḱakat́ sakam",
"pool-errorunknown": "Bań baḍayaḱ bhul",
"aboutsite": "babo̠tre {{SITENAME}}",
"aboutpage": "Project: Babo̠t",
- "copyright": "$1 re bhitrire ńamoḱa.",
+ "copyright": "$1 ᱨᱮ Content ᱧᱟᱢᱚᱜ-ᱟ ᱟᱨ ᱵᱟᱝᱠᱷᱟᱡᱽ ᱚᱞ ᱛᱟᱦᱮᱱᱟ",
"copyrightpage": "{{ns:project}}: Eḱteạr",
"currentevents": "Cạlit ghoṭnako",
"currentevents-url": "Project: Nitaḱ evenṭ ko",
"nosuchaction": "Noṅkanaḱ kạmi bạnuḱa",
"nosuchactiontext": "Noa URL re goṭa akan kạmi do ạnlekate baṅkana.\nAm do paseć mit́ṭen vul joṛaoem emakada se URL oltem vul akada.\nNoa do noṅkanaḱ menkana je {{SITENAME}} sayeṭre beoharen sofṭower re mit́ṭen vul menaḱa.",
"nosuchspecialpage": "Noṅkanaḱ asokay sakam do banuḱa",
- "nospecialpagetext": "<strong>Am do mit́ṭen beạn asokae sakamem nehor akada.</strong>\n[[Special:SpecialPages {{int:specialpages}}]]-re ạn asokae sakamkore mit́ṭen tạlikam ńama.",
+ "nospecialpagetext": "<strong>ᱟᱢ ᱫᱚ ᱡᱟᱸᱦᱟ ᱥᱟᱦᱴᱟ ᱞᱟᱹᱜᱤᱛ ᱮᱢ ᱱᱮᱦᱚᱨ ᱟᱠᱟᱫᱟ ᱚᱱᱟᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ </strong>\nᱡᱟᱸᱦᱟ ᱥᱟᱦᱴᱟᱠᱩ ᱱᱚᱸᱰᱮ ᱢᱮᱱᱟᱜ-ᱟ ᱚᱱᱟᱨᱮᱱᱟᱜ ᱛᱟᱹᱞᱠᱟᱹ ᱱᱚᱸᱰᱮᱢ ᱧᱟᱢᱟ [[Special:SpecialPages|{{int:specialpages}}]]᱾",
"error": "bhul",
"databaseerror": "Ḍaṭabase vul",
"databaseerror-error": "ᱦᱩᱲᱟᱹᱜ: $1",
"viewsource-title": "$1 renaḱ ńamoḱ ṭhại ńelmẽ",
"actionthrottled": "Kạmi reaḱ dhara bại",
"protectedpagetext": "Noa sakam do ol toṅge lạgit́te do bańcao gea.",
- "viewsourcetext": "Noa sakam do am ńel ar ńamoḱaḱ ṭhạiem kopi hatao daṛeaḱa:",
+ "viewsourcetext": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟᱢ ᱧᱮᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱟᱨᱮᱢ ᱠᱚᱯᱤ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾",
"viewyourtext": "Am do '''Amaḱ sompadon''' noa sakam ńel arem kopi hatao daṛeaḱa:",
"protectedinterface": "Noa sakam reaḱ babotko do wiki sofṭoyer reaḱ mit́ṭen inṭarfes khobore ema, onate noa do rukhiyạ doho hoeakana.",
"cascadeprotected": "Noa sakam do sompadon khon rukhiyạre menaḱa, karon sakam do latar reaḱ {{PLURAL:$1 gan sakam reaḱ gan sakam reaḱ}} bhitrire, oka sakam do (cascading) te rukhiyạ menaḱa:\n$2",
"newarticle": "(Nãwa)",
"newarticletext": "Am do oka mitṭen joṛaoem pańja akada, onaṭak do bạnuḱa.\nOna sakam tear lạgit́te, latar reaḱ baksore ol ehoṕmẽ (arhõ jạsti baḍae lạgit́te [$1 help page] pańjaemẽ).\nAm do judi nonḍe vulkatem heć akan khan, tobe amaḱ sendrakore '''back''' baṭon linmẽ.",
"noarticletext": "Nitoḱ noa sakamre do cet́olge bạnuḱa.\n\nAm menlekhan eṭaḱ sakamkore [[Special:Search/{{PAGENAME}}|search for this page title]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page]</span>.",
- "noarticletext-nopermission": "Noa sakamre do nitoḱ o̠l banuḱa.\n\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages,\nor <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>.",
+ "noarticletext-nopermission": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱱᱤᱛᱚᱜ ᱪᱮᱫᱜᱮ ᱚᱞ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾\n\nᱟᱢ [[Special:Search/{{PAGENAME}}|ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟᱨᱮᱱᱟᱜ ᱧᱤᱛᱩᱢᱮᱢ ᱥᱮᱸᱫᱨᱟ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ]] ᱮᱴᱟ ᱥᱟᱦᱴᱟ ᱠᱚᱨᱮᱦᱚ,\nor <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>.",
"userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" ńutuman jahãe beoharićaḱ ekaunṭ do baṅ resṭri hoeakana. Daya kate biḍạo katet́ ńelmẽ noa sakam do benoa/sompadonem menet́ kana se baṅ.",
"userpage-userdoesnotexist-view": "Beoharićaḱ \"$1\" ekaunṭ do baṅ resṭire akana.",
"blocked-notice-logextract": "Nui beoharić do nitoḱe esetgea.\nRefarens lạgit́te nahaḱ boloḱ do latare em hoena:",
+ "clearyourcache": "<strong>Note:</strong> After saving, you may have to bypass your browser's cache to see the changes.\n* <strong>Firefox / Safari:</strong> Hold <em>Shift</em> while clicking <em>Reload</em>, or press either <em>Ctrl-F5</em> or <em>Ctrl-R</em> (<em>⌘-R</em> on a Mac)\n* <strong>Google Chrome:</strong> Press <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> on a Mac)\n* <strong>Internet Explorer:</strong> Hold <em>Ctrl</em> while clicking <em>Refresh</em>, or press <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Go to <em>Menu → Settings</em> (<em>Opera → Preferences</em> on a Mac) and then to <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
"updated": "(Halot ruaṛ)",
"note": "'''Noṭ:'''",
"previewnote": "'''kheyalmẽ, noa do eken ńeloḱ lạgit.'''\nAmaḱ bodolaḱ kodo nit habićte bań rukhíạakana!",
- "continue-editing": "Toṅge calaḱkana",
+ "continue-editing": "ᱥᱚᱞᱦᱮ ᱡᱟᱭᱜᱟ ᱪᱟᱞᱟᱜ ᱢᱮ",
"editing": "Joṛao do purạena: $1",
"creating": "$1 sakam doe tear akada",
"editingsection": "Joṛao $1 (hạṭiń)",
"nocreate-loggedin": "Nãwã sakam tear lạgit́te am do ạidạri em baṅ hoeakana.",
"sectioneditnotsupported-title": "Pahaṭa sompadona do bae hataoeda",
"sectioneditnotsupported-text": "Noa sompadona sakamre pahaṭa sompadona do bae hataoeda",
- "permissionserrors": "Ạidạri vulko",
+ "permissionserrors": "á±\9fá±¹á±á±«á±\9fᱹᱨᱤ ᱦᱩᱲá±\9fá±¹á±\9c",
"permissionserrorstext": "Noa kạmi amaḱ ạidạri do banuḱa, {{PLURAL:$1 gan karon reaḱ gan karon reaḱ}} lạgit:",
"permissionserrorstext-withaction": "Amaḱ $2 kạmire ạydạri do bạnuḱa, Ona reaḱ {{PLURAL:$1 Karon/ Karonko}}:",
"recreate-moveddeleted-warn": "'''Sontorokme: am do arhõ doṛhate sakamem teyareda oka do sedayre get giḍiyen.\nAm do gunạnme cet́ noa joṛao kạmi am lạgit́te ganoḱ ase bań.\nNoa get ar tala ocok sakam nonḍe em hoyena dhok lagit́te.",
- "moveddeleted-notice": "Noa sakam do get giḍiyakana.\nGet ar ocoḱ giḍi sakam do latarre emakan reference lạgit em hoena.",
+ "moveddeleted-notice": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱜᱮᱫ ᱜᱤᱰᱤ ᱦᱩᱭ ᱟᱠᱟᱱᱟ᱾\nᱜᱮᱫ ᱥᱮ ᱵᱟᱸᱪᱟᱣ ᱥᱮ ᱚᱪᱚᱜ ᱜᱤᱰᱤᱭᱟᱠᱟᱱ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ reference ᱞᱟᱛᱟᱨᱨᱮ ᱮᱢ ᱦᱩᱭᱱᱟ᱾",
"log-fulllog": "Joto cạbi udugmẽ",
"edit-hook-aborted": "Huk hotete joto sompadonko bạgi hoeakana.\nNoa reaḱ jahan katha do bạnuḱa.",
"edit-gone-missing": "Sakam do baṅ halot ruạṛlena.\nPasecc: sakam do ocoǵ hoeakana.",
"page_first": "Pahilaḱ",
"page_last": "Mucạt́aḱ",
"histlegend": "Farak bachao: oka nãwã aroeko tulạoem menet́kan, onako cinhạ em kate boloḱ se latar baṭon linmẽ.<br />\nUnuduḱ: '''({{int:cur}})''' = nahaḱ nãwã aroeko saõte tulạo, '''({{int:last}})''' = laha reaḱ nãwã aroe sãote tulạo, '''{{int:minoreditletter}}''' = huḍiń sompadon.",
- "history-fieldset-title": "Sendray jaṛ",
+ "history-fieldset-title": "revision ᱞᱟᱹᱜᱤᱛ ᱥᱮᱸᱫᱨᱟ",
"history-show-deleted": "khạli get giḍiyaḱ koge",
- "histfirst": "adi laha-ak'",
- "histlast": "Nahak",
+ "histfirst": "ᱢᱟᱨᱮᱱᱟᱜ",
+ "histlast": "ᱱᱟᱣᱭᱟᱱᱟᱜ",
"historysize": "({{PLURAL:$1 1 bayeṭ $1 bayeṭko}})",
"historyempty": "(banuḱa)",
"history-feed-title": "Jạṛ nãwã aroy",
"shown-title": "Mit́ ṭen kateć sakam $1 {{PLURAL:$1|result|results}} nelmẽ",
"viewprevnext": "Ńelme ($1 {{int:pipe-separator}} $2) ($3)",
"searchmenu-exists": "'''Noa wiki re do \"[[:$1]] ńutum sakam menaḱa",
- "searchmenu-new": "wiki re [[:$1]]nãwã sakam tear",
+ "searchmenu-new": "ᱩᱭᱠᱤ ᱨᱮ [[:$1]] ᱱᱟᱣᱭᱟ ᱥᱟᱦᱴᱟ ᱛᱮᱭᱟᱨ",
"searchprofile-articles": "Menaḱaḱ sakamko",
"searchprofile-images": "Multimedia",
"searchprofile-everything": "Sanamaḱ koge",
"right-move-subpages": "Sakam saõte kạtic sakamko ocogmẽ",
"right-movefile": "Rẽtko ocogmẽ",
"right-upload": "Rẽtko rakabmẽ",
- "right-writeapi": "write API ᱵᱮᱵᱦᱟᱨ",
+ "right-writeapi": "ᱚᱞ API ᱨᱮᱱᱟᱜ ᱵᱮᱵᱷᱟᱨ",
"right-delete": "Sakamko get giḍiymẽ",
"newuserlogpage": "Laṛcaṛićaḱ tear cạbi",
"rightslog": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱟᱹᱭᱫᱟᱹᱨ ᱞᱚᱜᱽ",
"recentchanges-label-plusminus": "ᱥᱟᱦᱴᱟ ᱫᱚ ᱵᱚᱫᱚᱞᱮᱱᱟ ᱱᱤᱱᱟᱹᱜ ᱮᱞ ᱵᱟᱭᱤᱴᱥ ᱛᱮ",
"recentchanges-legend-heading": "<strong>ᱞᱤᱡᱮᱸᱰ:</strong>",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ᱟᱨᱦᱚᱸ ᱧᱮᱞᱢᱮ [[Special:NewPages|ᱱᱟᱶᱟ ᱥᱟᱦᱴᱟ ᱞᱤᱥᱴᱤ]])",
- "rcnotefrom": "$2 habić bodolak ko do latare ńeloḱkana",
+ "rcnotefrom": "$2 ᱱᱤᱛ ᱫᱷᱟᱹᱵᱤᱡᱽ ᱵᱚᱫᱚᱞ ᱟᱠᱟᱱ ᱠᱚᱫᱚ ᱞᱟᱛᱟᱨᱨᱮ ᱧᱮᱞᱚᱜ-ᱟ",
"rclistfrom": "Nãwã bodolko uduḱme $3 $2 khon ehoṕkate",
"rcshowhideminor": "$1 kaṭic culuń tońgeko",
"rcshowhideminor-show": "Uduḱme",
"emailmessage": "Mesag",
"emailsend": "Kulmẽ",
"usermessage-editor": "ᱥᱤᱥᱴᱚᱢ ᱨᱟᱭᱵᱟᱨ",
- "watchlist": "Inak' n'el ko",
+ "watchlist": "ᱧᱮᱞᱟᱜ ᱞᱤᱥᱴᱤ",
"mywatchlist": "Ńeloḱgoḱ tạlika",
"watchlistfor2": "$1 ($2) lạ̣gitte",
"watch": "Ńelme",
"unwatch": "bang nelok' a",
- "watchlist-details": "Baṅ purạo tạlikare {{PLURAL:$1ṭen sakam $1 ṭen sakam}} menaḱa (roṛ sakamko lekhare baṅ sapkate)",
+ "watchlist-details": "ᱵᱟᱝ ᱯᱩᱨᱟᱹᱣ ᱛᱟᱹᱞᱠᱟᱹᱨᱮ{{PLURAL:$1 ᱥᱟᱦᱴᱟ $1 ᱥᱟᱦᱴᱟ}} ᱢᱮᱱᱟᱜ-ᱟ (ᱨᱚᱲ ᱥᱟᱦᱴᱟ ᱠᱚᱦᱚᱸ)",
+ "wlheader-showupdated": "ᱟᱢᱟᱜ ᱢᱩᱪᱟᱹᱫ ᱵᱚᱞᱚᱝᱨᱮ ᱡᱟᱸᱦᱟᱸ ᱥᱟᱦᱴᱟ ᱠᱚᱢ ᱵᱚᱫᱚᱞ ᱞᱮᱫᱟ ᱚᱱᱟᱠᱩ ᱧᱮᱞᱚᱜ-ᱟ <strong>bold</strong>.",
"wlnote": "ᱞᱟᱛᱟᱨ ᱨᱮᱱᱟᱜ {{PLURAL:$1|ᱫᱚ ᱢᱩᱪᱟᱹᱫ ᱵᱚᱫᱚᱞ ᱠᱟᱱᱟ|ᱠᱚ ᱫᱚ ᱢᱩᱪᱟᱹᱫ <strong>$1</strong> ᱵᱚᱫᱚᱞᱠᱟᱱᱟ}} ᱢᱩᱪᱟᱹᱫ ᱨᱮ {{PLURAL:$2|ᱴᱟᱲᱟᱝ|<strong>$2</strong> ᱴᱟᱲᱟᱝ}}, $3, $4 ᱞᱮᱠᱟᱛᱮ ᱾",
- "wlshowlast": "Mucạtet́ udukmẽ $1 baje $2 maha",
+ "wlshowlast": "ᱢᱩᱪᱟᱹᱛ ᱩᱫᱩᱜᱢᱮ $1 ᱜᱷᱟᱱᱴᱟ $2 ᱢᱟᱦᱟ",
"watchlist-options": "Ńelok tạlika reak sonketko",
"watching": "Ńeloḱ kana...",
"enotif_reset": "ᱱᱤᱱᱦᱟᱹᱭᱢᱮ ᱡᱚᱛᱚ ᱥᱟᱦᱴᱟ ᱦᱤᱨᱤᱭᱟᱠᱟᱱᱟ",
"contributions-title": "$1 Beoharićaḱ kạmiko",
"mycontris": "Ińaḱ kạmiko",
"anoncontribs": "Ińaḱ kạmiko",
- "contribsub2": "$1 ($2) lạgitte",
+ "contribsub2": "$1 ($2) ᱞᱟᱹᱜᱤᱛᱛᱮ",
"nocontribs": "ᱱᱚᱶᱟ ᱮᱢᱟᱜ ᱥᱟᱶ ᱡᱚᱲᱟᱣᱟᱱ ᱵᱚᱫᱚᱞᱠᱚ ᱵᱟᱭ ᱧᱟᱢᱞᱮᱱᱟ |",
"uctop": "(ᱱᱤᱛᱚᱜ)",
"month": "Cando khon (ar etohopreaḱ)",
"whatlinkshere-hideredirs": "$1 arhõ unuduḱ",
"whatlinkshere-hidetrans": "Selet́ $1",
"whatlinkshere-hidelinks": "$1 joṛaoko",
- "whatlinkshere-hideimages": "$1 Chubi joṛaoko",
+ "whatlinkshere-hideimages": "$1 file ᱡᱚᱝᱲᱮᱠᱩ",
"whatlinkshere-filters": "Sapha",
"block": "Beoharić esedem",
"blockip": "Beoharić esedem",
"tooltip-t-whatlinkshere": "Sanam wiki sakam renaḱ list ar link do nonde",
"tooltip-t-recentchangeslinked": "Noa sakam re nitaḱ bodol akan sakam renaḱ linked",
"tooltip-feed-atom": "Noa sakam lạgit́ atom phiḍ",
- "tooltip-t-contributions": "Beoharićak kami reaḱ tạ̣lika",
- "tooltip-t-emailuser": "Nui beoharić mitṭen e-mail kulayme",
+ "tooltip-t-contributions": "ᱮᱱᱮᱢ ᱨᱮᱱᱟᱜ ᱛᱟᱹᱞᱠᱟᱹ {{GENDER:$1|this user}}",
+ "tooltip-t-emailuser": "ᱱᱩᱭ ᱵᱮᱵᱦᱟᱨᱤᱪ ᱢᱤᱫᱴᱮᱱ ᱤ ᱢᱮᱞ ᱠᱩᱞᱟᱭᱢᱮ",
"tooltip-t-upload": "Phayelko aploḍ̣me",
"tooltip-t-specialpages": "Jạruṛ patakureaḱ tạlikạ",
"tooltip-t-print": "Printoḱ lekan sakam",
"simpleantispam-label": "Enṭi espam ńel\nDo <strong>not</strong> noa purạome!",
"pageinfo-title": "\"$1\" ᱞᱟᱹᱜᱤᱫ ᱥᱩᱪᱱᱟ",
"pageinfo-header-basic": "ᱢᱩᱬ ᱥᱩᱪᱱᱟ",
- "pageinfo-header-edits": "Toṅgeko",
+ "pageinfo-header-edits": "ᱥᱟᱯᱲᱟᱣ ᱱᱟᱜᱟᱢ",
"pageinfo-header-restrictions": "ᱥᱟᱦᱴᱟ ᱵᱟᱧᱪᱟᱣ",
"pageinfo-header-properties": "ᱥᱟᱦᱴᱟ ᱜᱩᱱᱠᱚ",
"pageinfo-display-title": "ᱩᱫᱩᱜ ᱧᱩᱛᱩᱢ",
"pageinfo-robot-policy": "ᱨᱚᱵᱚᱴ ᱫᱟᱨᱟᱭᱛᱮ ᱩᱱᱩᱫᱩᱜ",
"pageinfo-robot-index": "ᱚᱪᱚᱣᱟᱜ",
"pageinfo-robot-noindex": "ᱵᱟᱝᱚᱪᱚ",
- "pageinfo-watchers": "Ńeńelkoaḱ nombor",
+ "pageinfo-watchers": "ᱥᱟᱦᱴᱟ ᱧᱮᱧᱮᱞᱤᱭᱟᱹ ᱠᱚᱣᱟᱜ ᱮᱞ",
"pageinfo-few-watchers": "$1 ᱠᱷᱚᱱ ᱠᱚᱢ {{PLURAL:$1|ᱧᱮᱧᱮᱞᱤᱭᱟᱹ|ᱧᱮᱧᱮᱞᱤᱭᱟᱹᱠᱚ}}",
"pageinfo-redirects-name": "ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟᱛᱮ ᱢᱚᱸᱦᱰᱟᱜᱠᱟᱱ ᱮᱞ",
"pageinfo-subpages-name": "ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱪᱟᱸᱜᱟ ᱥᱟᱦᱴᱟ ᱠᱚᱣᱟᱜ ᱮᱞ",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|galmarao]])",
"duplicate-defaultsort": "'''Sontoroḱmẽ:''' ḍifolṭ sajao reaḱ cạbi: $2 lahare ḍifolṭ sajao reaḱ sakam: ''$1'' e bae luturaḱ kana.",
"redirect": "ᱨᱮᱫ, ᱵᱮᱵᱷᱟᱨᱩᱭᱟᱹ, ᱥᱟᱦᱴᱟ, ᱧᱮᱞ-ᱟᱹᱨᱩ, ᱵᱟᱝᱠᱷᱟᱱ ᱞᱚᱜᱽ ID ᱫᱟᱨᱟᱭᱛᱮ ᱢᱚᱦᱰᱟ",
+ "redirect-summary": "ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱢᱚᱦᱰᱟ ᱟ ᱢᱤᱫ ᱨᱮᱫ (ᱮᱢᱟᱠᱟᱱ ᱨᱮᱫᱧᱩᱛᱩᱢ) ᱴᱷᱮᱱ, ᱢᱤᱫ ᱥᱟᱦᱴᱟ (ᱮᱢᱮᱱ ᱟᱹᱨᱩᱣᱟᱜ ID ᱟᱨᱵᱟᱝ ᱥᱟᱦᱴᱟ ID), ᱢᱤᱫ ᱵᱮᱵᱷᱟᱨᱩᱭᱟᱹ ᱥᱟᱦᱴᱟ (ᱮᱢᱮᱱ ᱮᱞᱩᱠ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ID ), ᱟᱨᱵᱟᱝ ᱢᱤᱫ ᱞᱚᱜᱽ ᱵᱚᱞᱚ (ᱮᱢᱮᱱ ᱞᱚᱜᱽ ID) ᱾ ᱵᱮᱵᱷᱟᱨᱟᱠᱟᱱ: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], ᱟᱨᱵᱟᱝ [[{{#Special:Redirect}}/logid/186]]",
"redirect-submit": "ᱥᱮᱱᱚᱜ",
"redirect-lookup": "ᱧᱮᱞᱢᱮ",
"redirect-value": "ᱫᱟᱢ:",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ᱥᱟᱛᱚᱢ|ᱥᱟᱛᱚᱢᱠᱩ}}]]: $2)",
"tags-active-yes": "ᱦᱮᱸ",
"tags-active-no": "ᱵᱟᱝ",
+ "tags-hitcount": "$1 {{PLURAL:$1|ᱟᱹᱨᱩ|ᱟᱹᱨᱩᱠᱚ}}",
"logentry-delete-delete": "$3 ᱥᱟᱦᱴᱟ $1 {{GENDER:$2|ᱜᱮᱫ ᱠᱮᱜ-ᱟᱭ}}",
"logentry-delete-restore": "$1 {{GENDER:$2|ᱨᱟᱠᱷᱟ ᱫᱚᱲᱦᱟ}} ᱠᱮᱜ-ᱟ ᱥᱟᱦᱴᱟ $3 ($4)",
"logentry-delete-revision": "$1 {{GENDER:$2|ᱵᱚᱫᱚᱞᱠᱮᱜ-ᱟᱭ}} ᱧᱮᱞᱚᱜᱟᱜ {{PLURAL:$5|ᱫᱚᱦᱲᱟᱭᱮᱱᱟᱜ|$5 ᱫᱚᱦᱲᱟᱭᱮᱱᱟᱜ ᱠᱚ}} $3: $4 ᱥᱟᱦᱴᱟ ᱪᱮᱛᱟᱱᱨᱮ",
"logentry-move-move": "$1 beoharić $3 sakam do $4 ńutumre {{GENDER:$2|ạcạr}} akada",
"logentry-move-move-noredirect": "$1 {{GENDER:$2|ᱩᱪᱟᱹᱲᱠᱮᱜ-ᱟᱭ}} ᱥᱟᱦᱴᱟ $3 to $4 ᱢᱚᱦᱰᱟ ᱵᱤᱱ ᱵᱟᱹᱜᱤ ᱠᱟᱛᱮ",
"logentry-move-move_redir": "$1 {{GENDER:$2|ᱩᱪᱟᱹᱲᱮᱱᱟ}} ᱥᱟᱦᱴᱟ $3 ᱠᱷᱚᱱ $4 ᱪᱮᱛᱟᱱ ᱢᱚᱸᱦᱰᱟ ᱦᱟᱠᱟᱱᱟ",
+ "logentry-patrol-patrol-auto": "$1 ᱟᱡᱛᱮᱜᱮ {{GENDER:$2|ᱪᱤᱱᱦᱟᱹᱭᱮᱱᱟ}} $4 ᱧᱮᱞᱟᱹᱨᱩ $3 ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱾",
"logentry-newusers-create": "Beoharićaḱ hisạb khata $1 do jhićena",
"logentry-newusers-autocreate": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱷᱟᱛᱟ $1 ᱫᱚ {{GENDER:$2|ᱛᱮᱭᱟᱨᱮᱱᱟ}} ᱟᱡᱛᱮᱜᱮ",
"logentry-upload-upload": "$1 {{GENDER:$2|rakaṕ akadae}} $3",
"diff-multi-sameuser": "({{PLURAL:$1|1=Vmesna redakcija|$1 vmesna redakcija|$1 vmesni redakciji|$1 vmesne redakcije|$1 vmesnih redakcij}} istega uporabnika {{PLURAL:$1|ni prikazana|nista prikazani|niso prikazane|ni prikazanih}})",
"diff-multi-otherusers": "({{PLURAL:$1|1=Vmesna redakcija|$1 vmesna redakcija|$1 vmesni redakciji|$1 vmesne redakcije|$1 vmesnih redakcij}} {{PLURAL:$2|1=drugega uporabnika|$2 uporabnikov}} {{PLURAL:$1|ni prikazana|nista prikazani|niso prikazane|ni prikazanih}})",
"diff-multi-manyusers": "({{PLURAL:$1|$1 vmesna redakcija|$1 vmesni redakciji|$1 vmesne redakcije|$1 vmesnih redakcij}} več kot $2 {{PLURAL:$2|uporabnika|uporabnikov}} {{PLURAL:$1|ni prikazana|nista prikazani|niso prikazane|ni prikazanih}})",
+ "diff-paragraph-moved-tonew": "Odstavek je premaknjen. Kliknite, da skočite na novo nahajališče.",
+ "diff-paragraph-moved-toold": "Odstavek je bil premaknjen. Kliknite, da skočite na staro nahajališče.",
"difference-missing-revision": "{{PLURAL:$2|Ene redakcije|$2 redakcij}} razlike ($1) {{PLURAL:$2|nisem}} našel.\n\nPo navadi se to zgodi, ko sledite zastareli povezavi na razliko redakcij strani, ki jo je nekdo izbrisal.\nPodrobnosti lahko najdete v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} dnevniku brisanja].",
"searchresults": "Izid iskanja",
"searchresults-title": "Zadetki za povpraševanje »$1«",
"recentchangesdays-max": "Največ $1 {{PLURAL:$1|dan|dneva|dnevi|dni}}",
"recentchangescount": "Privzeto število prikazanih urejanj:",
"prefs-help-recentchangescount": "Vključuje zadnje spremembe, zgodovine strani in dnevniške zapise.",
- "prefs-help-watchlist-token2": "To je skrivni ključ do spletnega vira vašega spiska nadzorov. Kdor ve zanj, lahko bere vaš spisek nadzorov, zato ključa ne delite. [[Special:ResetTokens|Kliknite tukaj, če ga želite ponastaviti]].",
"savedprefs": "Spremembe smo uspešno shranili.",
"savedrights": "Uporabniške skupine {{GENDER:$1|$1}} smo shranili.",
"timezonelegend": "Časovni pas",
"recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
"recentchangescount": "Број измена за приказ:",
"prefs-help-recentchangescount": "Подразумева скорашње измене, историје страница и дневнике.",
- "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да види Ваша надгледања; стога, кључ немојте одавати никоме. \nАко је потребно, кључ можете [[Special:ResetTokens|ресетовати]].",
"savedprefs": "Ваша подешавања су сачувана.",
"savedrights": "Корисничке групе за {{GENDER:$1|$1}} су сачуване.",
"timezonelegend": "Временска зона:",
"recentchangesdays-max": "Maximalt $1 {{PLURAL:$1|dygn}}",
"recentchangescount": "Antal redigeringar som visas som standard:",
"prefs-help-recentchangescount": "Detta inkluderar senaste ändringarna, sidhistorik och loggar.",
- "prefs-help-watchlist-token2": "Detta är den hemliga nyckeln till webbflödet i din bevakningslista.\nNågon som vet den kommer att kunna läsa din bevakningslista, så dela inte ut den.\n[[Special:ResetTokens|Klicka här om du behöver återställa den]].",
"savedprefs": "Dina inställningar har sparats",
"savedrights": "Användargrupperna för {{GENDER:$1|$1}} har sparats.",
"timezonelegend": "Tidszon:",
"recentchangesdays-max": "மிக அதிகமாக $1 {{PLURAL:$1|நாள்|நாட்கள்}}",
"recentchangescount": "மொத்தத் தொகுப்புக்களின் எண்ணிக்கையைத் தானாகவே காட்ட:",
"prefs-help-recentchangescount": "அண்மைய மாற்றங்களையும், பக்கத்தின் வரலாறுகளையும் பதிவேட்டுப் பதிவுகளையும் உள்ளடக்கியதாகும்.",
- "prefs-help-watchlist-token2": "உங்கள் கவனிப்புப்பட்டியலின் வலை ஓடைக்கு இது இரகசிய சாவி.\nஇதை அறிந்த எவரும் உங்கள் கவனிப்பு பட்டியலை வாசிக்கலாம், எனவே இதை பகிராதீர்கள்.\nதேவை ஏற்படின், [[Special:ResetTokens|நீங்கள் அதனை புதுப்பிக்கலாம்]].",
"savedprefs": "உங்கள் விருப்பத்தேர்வுகள் சேமிக்கப்பட்டுள்ளன.",
"savedrights": "{{GENDER:$1|$1}}-க்கான பயனர் உரிமைகள் சேமிக்கப்பட்டன.",
"timezonelegend": "நேர வலயம்:",
"LR Guanzon"
]
},
- "tog-underline": "Pagsasalungguhit ng kawing:",
+ "tog-underline": "Pagsasalungguhit ng link:",
"tog-hideminor": "Itago ang mga maliliit na pagbabago mula sa mga huling pagbabago",
"tog-hidepatrolled": "Itago ang mga napatrolyang pagbabago mula sa mga huling pagbabago",
"tog-newpageshidepatrolled": "Itago ang mga napatrolyang pahina mula talaan ng bagong pahina",
"mytalk": "Usapan",
"anontalk": "Usapan",
"navigation": "Paglilibot",
- "and": ", at",
+ "and": " at",
"faq": "Mga malilimit itanong",
"actions": "Mga kilos",
"namespaces": "Mga ngalan-espasyo",
"history_small": "kasaysayan",
"updatedmarker": "isinapanahon mula noong huli kong pagdalaw",
"printableversion": "Bersiyong maililimbag",
- "permalink": "Permanenteng kawing",
+ "permalink": "Permanenteng link",
"print": "Ilimbag",
"view": "Tingnan",
"view-foreign": "Tingnan sa $1",
"edithelp": "Tulong sa pagbabago",
"helppage-top-gethelp": "Tulong",
"mainpage": "Unang Pahina",
- "mainpage-description": "Unang Pahina",
+ "mainpage-description": "Unang pahina",
"policy-url": "Project:Patakaran",
"portal": "Puntahan ng pamayanan",
"portal-url": "Project:Puntahan ng pamayanan",
"anontalk": "اس آئی پی پتہ کا تبادلۂ خیال",
"navigation": "رہنمائی",
"and": " اور",
- "faq": "عاÙ\85 Ø·Ù\88ر Ù¾ر پوچھے جانے والے سوالات",
+ "faq": "اکثر پوچھے جانے والے سوالات",
"actions": "اقدامات",
"namespaces": "نام فضا",
"variants": "متغیرات",
"diff-multi-sameuser": "(ایک ہی صارف کا {{PLURAL: $1 |ایک درمیانی نسخہ نہیں دکھایا گیا| $1 درمیانی نسخے نہیں دکھائے گئے}})",
"diff-multi-otherusers": "({{PLURAL:$2|ایک دوسرے صارف|$2 صارفین}} {{PLURAL:$1|کا ایک درمیانی نسخہ نہیں دکھایا گیا|$1 کے درمیانی نسخے نہیں دکھائے گئے}})",
"diff-multi-manyusers": "($2 سے زیادہ {{PLURAL:$2|صارف|صارفین}} {{PLURAL:$1|کا ایک درمیانی نسخہ نہیں دکھایا گیا|$1 کے درمیانی نسخے نہیں دکھائے گئے}})",
+ "diff-paragraph-moved-tonew": "عبارت ہٹا دی گئی تھی۔ نئے مقام پر جانے کے لیے کلک کریں۔",
+ "diff-paragraph-moved-toold": "عبارت ہٹا دی گئی تھی۔ پرانے مقام پر واپس جانے کے لیے کلِک کریں۔",
"difference-missing-revision": "اس فرق ($1) {{PLURAL:$2|کا ایک نسخہ نہیں ملا|$2 کے نسخے نہیں ملے}}۔\n\nعموماً ایسا اس وقت ہوتا ہے جب کسی حذف شدہ صفحہ کے نسخوں کے درمیان میں فرق تلاش کرنے کی کوشش کی جائے۔\nمزید تفصیلات [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} نوشتہ حذف شدگی] میں دیکھی جا سکتی ہیں۔",
"searchresults": "تلاش کے نتائج",
"searchresults-title": "«$1» کے نتائج تلاش",
"recentchangesdays-max": "زیادہ سے زیادہ $1 {{PLURAL:$1|دن}}",
"recentchangescount": "دکھائی جانے والی ترامیم کی تعداد:",
"prefs-help-recentchangescount": "اِس میں حالیہ تبدیلیاں، تاریخچے اور نوشتہ جات شامل ہیں۔",
- "prefs-help-watchlist-token2": "یہ آپ کی زیر نظر فہرست کے ویب فیڈ کی خفیہ کلید ہے۔\nاسے خفیہ رکھیں، تاکہ کوئی دوسرا شخص آپ کی زیر نظر فہرست نہ دیکھ سکے۔\nاگر آپ کو کلید تبدیل کرنی ہو تو [[Special:ResetTokens|یہاں کلک کریں]]۔",
"savedprefs": "آپ کی ترجیحات محفوظ ہوگئیں۔",
"savedrights": "{{GENDER:$1|$1}} کے اختیارات محفوظ ہو گئے۔",
"timezonelegend": "منطقۂ وقت:",
"statistics-header-hooks": "دیگر اعداد و شمار",
"statistics-articles": "مندرج صفحات",
"statistics-pages": "صفحات",
- "statistics-pages-desc": "(ویکی اقتباسات کے کل صفحات، بشمولِ تبادلۂ خیال، رجوع مکررات وغیرہ۔)",
+ "statistics-pages-desc": "(وکی اقتباسات کے کل صفحات، بشمولِ تبادلۂ خیال، رجوع مکررات وغیرہ۔)",
"statistics-files": "اپلوڈ کردہ فائلیں",
"statistics-edits": "{{SITENAME}} کے آغاز سے کل صفحاتی ترامیم",
"statistics-edits-average": "فی صفحہ اوسط ترامیم",
"logentry-patrol-patrol": "$1 نے صفحہ $3 کے نسخہ $4 کو مراجعت شدہ {{GENDER:$2|نشان زد کیا}}",
"logentry-patrol-patrol-auto": "$1 نے صفحہ $3 کے نسخہ $4 کو خودکار طور پر مراجعت شدہ {{GENDER:$2|نشان زد کیا}}",
"logentry-newusers-newusers": "صارف کھاتہ $1 {{GENDER:$2|تخلیق ہو چکا ہے}}",
- "logentry-newusers-create": "صارف کھاتہ $1 {{GENDER:$2|بنایا گیا}}",
+ "logentry-newusers-create": "$1 کے نام سے صارف کھاتہ {{GENDER:$2|بنایا گیا}}",
"logentry-newusers-create2": "$1 نے صارف کھاتہ $3 {{GENDER:$2|تخلیق کیا}}",
"logentry-newusers-byemail": "$1 نے صارف کھاتہ $3 {{GENDER:$2|تخلیق کیا}} اور پاس ورڈ بذریعہ برقی خط روانہ کیا گیا ہے",
"logentry-newusers-autocreate": "صارف کھاتہ $1 خودکار طور پر {{GENDER:$2|تخلیق ہوا}}",
"diff-multi-sameuser": "(未显示同一用户的$1个中间版本)",
"diff-multi-otherusers": "(未显示{{PLURAL:$1|另一用户|$2个用户}}的{{PLURAL:$1|$1个中间版本}})",
"diff-multi-manyusers": "(未显示超过$2个用户的$1个中间版本)",
+ "diff-paragraph-moved-tonew": "段落已移动。点击跳到新位置。",
+ "diff-paragraph-moved-toold": "段落已移动。点击跳到旧位置。",
"difference-missing-revision": "此差异对比的{{PLURAL:$2|$2个版本}}($1){{PLURAL:$2|没有}}找到。\n\n这通常是因为进入了一个已被删除的页面的版本差异对比链接。\n详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。",
"searchresults": "搜索结果",
"searchresults-title": "“$1”的搜索结果",
"prefs-watchlist-edits": "在监视列表中显示的更改的最大数目:",
"prefs-watchlist-edits-max": "最大数目:1000",
"prefs-watchlist-token": "监视列表密钥:",
+ "prefs-watchlist-managetokens": "管理令牌",
"prefs-misc": "其他",
"prefs-resetpass": "更改密码",
"prefs-changeemail": "更改或移除电子邮件地址",
"recentchangesdays-max": "最多$1天",
"recentchangescount": "默认显示的编辑数:",
"prefs-help-recentchangescount": "这包括最近更改、页面历史和日志。",
- "prefs-help-watchlist-token2": "这是您的监视列表的网络feed密钥。\n任何拥有者均可以浏览您的监视列表,因此不要公开该密钥。\n如果有需要,[[Special:ResetTokens|您可以重置密钥]]。",
+ "prefs-help-tokenmanagement": "您可以查看并重置您账户的密钥,它用来访问您监视列表的Web订阅源。任何知道密钥的人都将可以阅读您的监视列表,所以不要分享它。",
"savedprefs": "您的系统设置已保存。",
"savedrights": "{{GENDER:$1|$1}}的用户组已被保存。",
"timezonelegend": "时区:",
"apisandbox": "API 沙盒",
"apisandbox-jsonly": "需要JavaScript以使用API沙盒。",
"apisandbox-api-disabled": "API在该网站停用。",
- "apisandbox-intro": "使用这个页面来试验<strong>MediaWiki Web 服务应用程序接口(API)</strong>。\n欲知API使用详情,请参阅[[mw:API:Main page|API文档]]。\n例如:[https://www.mediawiki.org/wiki/API#A_simple_example 取得某个主页的内容],然后选择一个操作来看更多范例。\n\n请注意,虽然这是一个沙盒,但是您在这个页面上的改动可能会修改维基。",
+ "apisandbox-intro": "使用这个页面来试验<strong>MediaWiki Web 服务应用程序接口(API)</strong>。欲知API使用详情,请参阅[[mw:API:Main page|API文档]]。例如:[https://www.mediawiki.org/wiki/API#A_simple_example 取得某个主页的内容],然后选择一个操作来看更多范例。\n\n请注意,虽然这是一个沙盒,但是您在这个页面上的改动可能会修改维基。",
"apisandbox-fullscreen": "展开面板",
"apisandbox-fullscreen-tooltip": "展开沙盒面板以填充浏览器窗口。",
"apisandbox-unfullscreen": "显示页面",
"articleexists": "该名称的页面已存在,或者您使用的名称无效。请另选一名。",
"cantmove-titleprotected": "您无法将页面移动到该位置,因为新标题已被保护以防止创建。",
"movetalk": "移动关联的讨论页",
- "move-subpages": "移动子页面(上至$1页)",
+ "move-subpages": "移动子页面(最多$1页)",
"move-talk-subpages": "如果可能,移动子对话页面(上至$1页)",
"movepage-page-exists": "页面$1已存在,无法自动覆盖。",
"movepage-page-moved": "页面$1已经移动到$2。",
"variantname-gan-hans": "赣语(简体)",
"variantname-gan-hant": "赣语(繁体)",
"variantname-kk-cyrl": "kk-cyrl",
+ "variantname-crh-latn": "克里米亚鞑靼文(拉丁)",
+ "variantname-crh-cyrl": "克里米亚鞑靼文(西里尔)",
"metadata": "元数据",
"metadata-help": "此文件中包含有额外的信息。这些信息可能是由数码相机或扫描仪在创建或数字化过程中所添加的。如果文件自初始状态已受到修改,一些详细说明可能无法反映修改后的文件。",
"metadata-expand": "显示详细资料",
"recentchangesdays-max": "最多 $1 {{PLURAL:$1|天}}",
"recentchangescount": "預設顯示的編輯數:",
"prefs-help-recentchangescount": "這包含近期變更、頁面歷史以及日誌。",
- "prefs-help-watchlist-token2": "訂閱您的監視清單所需的密鑰。\n任何人只要知道密鑰就能夠讀取您的監視清單,所以請勿任意與它人共享。\n若有需要 [[Special:ResetTokens|您可重設密鑰]]。",
"savedprefs": "已儲存您的偏好設定。",
"savedrights": "已儲存 {{GENDER:$1|$1}} 的使用者權限。",
"timezonelegend": "時區:",
"rcfilters-filtergroup-authorship": "貢獻的作者",
"rcfilters-filter-editsbyself-label": "您的編輯",
"rcfilters-filter-editsbyself-description": "您的貢獻",
- "rcfilters-filter-editsbyother-label": "其他人的更改",
+ "rcfilters-filter-editsbyother-label": "其他人的變更",
"rcfilters-filter-editsbyother-description": "除了您以外的所有更改",
"rcfilters-filtergroup-userExpLevel": "使用者註冊及經驗",
"rcfilters-filter-user-experience-level-registered-label": "已註冊",
<?php
-/** Crimean Turkish (Qırımtatarca)
+/** Crimean Tatar (Qırımtatarca)
*
* To improve a translation please visit https://translatewiki.net
*
<?php
-/** Crimean Turkish (Cyrillic script) (къырымтатарджа (Кирилл))
+/** Crimean Tatar (Cyrillic script) (къырымтатарджа (Кирилл))
*
* To improve a translation please visit https://translatewiki.net
*
<?php
-/** Crimean Turkish (Latin script) (qırımtatarca (Latin))
+/** Crimean Tatar (Latin script) (qırımtatarca (Latin))
*
* To improve a translation please visit https://translatewiki.net
*
* Throw an error to the user. Doesn't respect --quiet, so don't use
* this for non-error output
* @param string $err The error to display
- * @param int $die If > 0, go ahead and die out using this int as the code
+ * @param int $die Deprecated since 1.31, use Maintenance::fatalError() instead
*/
protected function error( $err, $die = 0 ) {
+ if ( intval( $die ) !== 0 ) {
+ wfDeprecated( __METHOD__ . '( $err, $die )', '1.31' );
+ $this->fatalError( $err, intval( $die ) );
+ }
$this->outputChanneled( false );
if ( PHP_SAPI == 'cli' ) {
fwrite( STDERR, $err . "\n" );
} else {
print $err;
}
- $die = intval( $die );
- if ( $die > 0 ) {
- die( $die );
- }
+ }
+
+ /**
+ * Output a message and terminate the current script.
+ *
+ * @param string $msg Error message
+ * @param int $exitCode PHP exit status. Should be in range 1-254.
+ * @since 1.31
+ */
+ protected function fatalError( $msg, $exitCode = 1 ) {
+ $this->error( $msg );
+ exit( $exitCode );
}
private $atLineStart = true;
$joined = implode( ', ', $missing );
$msg = "The following extensions are required to be installed "
. "for this script to run: $joined. Please enable them and then try again.";
- $this->error( $msg, 1 );
+ $this->fatalError( $msg );
}
}
# Abort if called from a web server
if ( isset( $_SERVER ) && isset( $_SERVER['REQUEST_METHOD'] ) ) {
- $this->error( 'This script must be run from the command line', true );
+ $this->fatalError( 'This script must be run from the command line' );
}
if ( $IP === null ) {
- $this->error( "\$IP not set, aborting!\n" .
- '(Did you forget to call parent::__construct() in your maintenance script?)', 1 );
+ $this->fatalError( "\$IP not set, aborting!\n" .
+ '(Did you forget to call parent::__construct() in your maintenance script?)' );
}
# Make sure we can handle script parameters
if ( !defined( 'HPHP_VERSION' ) && !ini_get( 'register_argc_argv' ) ) {
- $this->error( 'Cannot get command line arguments, register_argc_argv is set to false', true );
+ $this->fatalError( 'Cannot get command line arguments, register_argc_argv is set to false' );
}
// Send PHP warnings and errors to stderr instead of stdout.
}
if ( !is_readable( $settingsFile ) ) {
- $this->error( "A copy of your installation's LocalSettings.php\n" .
+ $this->fatalError( "A copy of your installation's LocalSettings.php\n" .
"must exist and be readable in the source directory.\n" .
- "Use --conf to specify it.", true );
+ "Use --conf to specify it." );
}
$wgCommandLineMode = true;
fwrite( $this->stderr, $string . "\n" );
}
}
-
- function fatalError( $msg ) {
- $this->error( "$msg\n", 1 );
- }
}
class ExportProgressFilter extends DumpFilter {
$content = file_get_contents( $this->getOption( 'file' ) );
MediaWiki\restoreWarnings();
if ( $content === false ) {
- $this->error( 'Unable to open input file', 1 );
+ $this->fatalError( 'Unable to open input file' );
}
$filename = basename( $this->getOption( 'file' ) );
$loops = $this->getOption( 'loops', 1 );
if ( $loops < 1 ) {
- $this->error( 'Invalid number of loops specified', true );
+ $this->fatalError( 'Invalid number of loops specified' );
}
$startUsage = getrusage();
$startTime = microtime( true );
public function execute() {
global $wgUseSquid, $wgSquidServers;
if ( !$wgUseSquid ) {
- $this->error( "Squid purge benchmark doesn't do much without squid support on.", true );
+ $this->fatalError( "Squid purge benchmark doesn't do much without squid support on." );
} else {
$this->output( "There are " . count( $wgSquidServers ) . " defined squid servers:\n" );
if ( $this->hasOption( 'count' ) ) {
public function execute() {
$html = file_get_contents( $this->getOption( 'file' ) );
if ( $html === false ) {
- $this->error( "Unable to open input file", 1 );
+ $this->fatalError( "Unable to open input file" );
}
if ( $this->hasOption( 'driver' ) || $this->hasOption( 'tidy-config' ) ) {
$config = json_decode( $this->getOption( 'tidy-config', '{}' ), true );
if ( !is_array( $config ) ) {
- $this->error( "Invalid JSON tidy config", 1 );
+ $this->fatalError( "Invalid JSON tidy config" );
}
$config += [ 'driver' => $this->getOption( 'driver', 'RemexHtml' ) ];
$driver = MWTidy::factory( $config );
} else {
$driver = MWTidy::singleton();
if ( !$driver ) {
- $this->error( "Tidy disabled or not installed", 1 );
+ $this->fatalError( "Tidy disabled or not installed" );
}
}
} elseif ( $this->hasOption( "userid" ) ) {
$user = User::newFromId( $this->getOption( 'userid' ) );
} else {
- $this->error( "A \"user\" or \"userid\" must be set to change the password for", true );
+ $this->fatalError( "A \"user\" or \"userid\" must be set to change the password for" );
}
if ( !$user || !$user->getId() ) {
- $this->error( "No such user: " . $this->getOption( 'user' ), true );
+ $this->fatalError( "No such user: " . $this->getOption( 'user' ) );
}
$password = $this->getOption( 'password' );
try {
$user->saveSettings();
$this->output( "Password set for " . $user->getName() . "\n" );
} catch ( PasswordError $pwe ) {
- $this->error( $pwe->getText(), true );
+ $this->fatalError( $pwe->getText() );
}
}
}
// Maybe they're using mediawiki/vendor?
$lockLocation = "$IP/vendor/composer.lock";
if ( !file_exists( $lockLocation ) ) {
- $this->error(
- 'Could not find composer.lock file. Have you run "composer install --no-dev"?',
- 1
+ $this->fatalError(
+ 'Could not find composer.lock file. Have you run "composer install --no-dev"?'
);
}
}
}
}
if ( $found ) {
- $this->error(
+ $this->fatalError(
'Error: your composer.lock file is not up to date. ' .
- 'Run "composer update --no-dev" to install newer dependencies',
- 1
+ 'Run "composer update --no-dev" to install newer dependencies'
);
} else {
// We couldn't find any out-of-date dependencies, so assume everything is ok!
$username = wfMessage( 'spambot_username' )->text();
$wgUser = User::newSystemUser( $username );
if ( !$wgUser ) {
- $this->error( "Invalid username specified in 'spambot_username' message: $username", true );
+ $this->fatalError( "Invalid username specified in 'spambot_username' message: $username" );
}
// Hack: Grant bot rights so we don't flood RecentChanges
$wgUser->addGroup( 'bot' );
$spec = $this->getArg();
$like = LinkFilter::makeLikeArray( $spec );
if ( !$like ) {
- $this->error( "Not a valid hostname specification: $spec", true );
+ $this->fatalError( "Not a valid hostname specification: $spec" );
}
if ( $this->hasOption( 'all' ) ) {
$title = $verified;
}
if ( is_null( $title ) ) {
- $this->error( "Something awry; empty title.", true );
+ $this->fatalError( "Something awry; empty title." );
}
$ns = $title->getNamespace();
$dest = $title->getDBkey();
$iterator = $tempRepo->getBackend()->getFileList( [ 'dir' => $dir, 'adviseStat' => 1 ] );
$this->output( "Deleting orphaned temp files...\n" );
if ( strpos( $dir, '/local-temp' ) === false ) { // sanity check
- $this->error( "Temp repo is not using the temp container.", 1 ); // die
+ $this->fatalError( "Temp repo is not using the temp container." );
}
$i = 0;
$batch = []; // operation batch
if ( $this->hasOption( 'tidy' ) ) {
global $wgUseTidy;
if ( !$wgUseTidy ) {
- $this->error( 'Tidy was requested but $wgUseTidy is not set in LocalSettings.php', true );
+ $this->fatalError( 'Tidy was requested but $wgUseTidy is not set in LocalSettings.php' );
}
$this->options->setTidy( true );
}
unset( $var );
$arg = $this->getArg( 0 );
if ( !is_file( $arg ) ) {
- $this->error( "$arg is not a file.", true );
+ $this->fatalError( "$arg is not a file." );
}
require $arg;
unset( $arg );
protected function handleExtensionFunctions( $realName, $value ) {
foreach ( $value as $func ) {
if ( $func instanceof Closure ) {
- $this->error( "Error: Closures cannot be converted to JSON. " .
- "Please move your extension function somewhere else.", 1
+ $this->fatalError( "Error: Closures cannot be converted to JSON. " .
+ "Please move your extension function somewhere else."
);
}
// check if $func exists in the global scope
if ( function_exists( $func ) ) {
- $this->error( "Error: Global functions cannot be converted to JSON. " .
- "Please move your extension function ($func) into a class.", 1
+ $this->fatalError( "Error: Global functions cannot be converted to JSON. " .
+ "Please move your extension function ($func) into a class."
);
}
}
}
foreach ( $handlers as $func ) {
if ( $func instanceof Closure ) {
- $this->error( "Error: Closures cannot be converted to JSON. " .
- "Please move the handler for $hookName somewhere else.", 1
+ $this->fatalError( "Error: Closures cannot be converted to JSON. " .
+ "Please move the handler for $hookName somewhere else."
);
}
// Check if $func exists in the global scope
if ( function_exists( $func ) ) {
- $this->error( "Error: Global functions cannot be converted to JSON. " .
- "Please move the handler for $hookName inside a class.", 1
+ $this->fatalError( "Error: Global functions cannot be converted to JSON. " .
+ "Please move the handler for $hookName inside a class."
);
}
}
'adviseStat' => true // avoid HEADs
] );
if ( $srcPathsRel === null ) {
- $this->error( "Could not list files in $container.", 1 ); // die
+ $this->fatalError( "Could not list files in $container." );
}
}
'adviseStat' => true // avoid HEADs
] );
if ( $dstPathsRel === null ) {
- $this->error( "Could not list files in $container.", 1 ); // die
+ $this->fatalError( "Could not list files in $container." );
}
$this->statCache = [];
foreach ( $dstPathsRel as $dstPathRel ) {
$srcPathsRel = $src->getFileList( [
'dir' => $src->getRootStoragePath() . "/$backendRel" ] );
if ( $srcPathsRel === null ) {
- $this->error( "Could not list files in source container.", 1 ); // die
+ $this->fatalError( "Could not list files in source container." );
}
$dstPathsRel = $dst->getFileList( [
'dir' => $dst->getRootStoragePath() . "/$backendRel" ] );
if ( $dstPathsRel === null ) {
- $this->error( "Could not list files in destination container.", 1 ); // die
+ $this->fatalError( "Could not list files in destination container." );
}
// Get the list of destination files
$relFilesDstSha1 = [];
$status = $dst->prepare( [ 'dir' => dirname( $dstPath ), 'bypassReadOnly' => 1 ] );
if ( !$status->isOK() ) {
$this->error( print_r( $status->getErrorsArray(), true ) );
- $this->error( "$wikiId: Could not copy $srcPath to $dstPath.", 1 ); // die
+ $this->fatalError( "$wikiId: Could not copy $srcPath to $dstPath." );
}
$ops[] = [ 'op' => 'store',
'src' => $fsFile->getPath(), 'dst' => $dstPath, 'overwrite' => 1 ];
$elapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 );
if ( !$status->isOK() ) {
$this->error( print_r( $status->getErrorsArray(), true ) );
- $this->error( "$wikiId: Could not copy file batch.", 1 ); // die
+ $this->fatalError( "$wikiId: Could not copy file batch." );
} elseif ( count( $copiedRel ) ) {
$this->output( "\n\tCopied these file(s) [{$elapsed_ms}ms]:\n\t" .
implode( "\n\t", $copiedRel ) . "\n\n" );
$elapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 );
if ( !$status->isOK() ) {
$this->error( print_r( $status->getErrorsArray(), true ) );
- $this->error( "$wikiId: Could not delete file batch.", 1 ); // die
+ $this->fatalError( "$wikiId: Could not delete file batch." );
} elseif ( count( $deletedRel ) ) {
$this->output( "\n\tDeleted these file(s) [{$elapsed_ms}ms]:\n\t" .
implode( "\n\t", $deletedRel ) . "\n\n" );
$dstKey = $this->getOption( 'dst' );
if ( !isset( $wgJobQueueMigrationConfig[$srcKey] ) ) {
- $this->error( "\$wgJobQueueMigrationConfig not set for '$srcKey'.", 1 );
+ $this->fatalError( "\$wgJobQueueMigrationConfig not set for '$srcKey'." );
} elseif ( !isset( $wgJobQueueMigrationConfig[$dstKey] ) ) {
- $this->error( "\$wgJobQueueMigrationConfig not set for '$dstKey'.", 1 );
+ $this->fatalError( "\$wgJobQueueMigrationConfig not set for '$dstKey'." );
}
$types = ( $this->getOption( 'type' ) === 'all' )
$user = User::newFromName( $username );
if ( !is_object( $user ) ) {
- $this->error( "invalid username.", true );
+ $this->fatalError( "invalid username." );
}
$exists = ( 0 !== $user->idForName() );
if ( $exists && !$force ) {
- $this->error( "Account exists. Perhaps you want the --force option?", true );
+ $this->fatalError( "Account exists. Perhaps you want the --force option?" );
} elseif ( !$exists && !$password ) {
- $this->error( "Argument <password> required!", false );
+ $this->error( "Argument <password> required!" );
$this->maybeHelp( true );
} elseif ( $exists ) {
$inGroups = $user->getGroups();
$user->saveSettings();
}
} catch ( PasswordError $pwe ) {
- $this->error( $pwe->getText(), true );
+ $this->fatalError( $pwe->getText() );
}
}
$outfile = $this->getArg( 1 );
if ( !is_readable( $infile ) && $infile !== 'php://stdin' ) {
- $this->error( "Cannot open input file $infile for reading", 1 );
+ $this->fatalError( "Cannot open input file $infile for reading" );
}
$file = fopen( $infile, 'r' );
if ( $file === false ) {
- $this->error( "Cannot read input file $infile", 1 );
+ $this->fatalError( "Cannot read input file $infile" );
}
try {
" (out of $i) passwords to $outfile\n"
);
} catch ( \Cdb\Exception $e ) {
- $this->error( "Error writing cdb file: " . $e->getMessage(), 2 );
+ $this->fatalError( "Error writing cdb file: " . $e->getMessage(), 2 );
}
}
}
$user = User::newFromName( $username );
}
if ( !$user ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
$wgUser = $user;
# Setup
if ( !$file ) {
- $this->error( "Unable to read file, exiting", true );
+ $this->fatalError( "Unable to read file, exiting" );
}
$dbw = $this->getDB( DB_MASTER );
// in order to hide it in RecentChanges.
$user = User::newFromName( 'MediaWiki default' );
if ( !$user ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
$user->addGroup( 'bot' );
$wgUser = $user;
$this->fetchMessageInfo( false, $messageInfo );
} else {
if ( !isset( $langCodes[$langCode] ) ) {
- $this->error( 'Invalid language code: ' . $langCode, 1 );
+ $this->fatalError( 'Invalid language code: ' . $langCode );
}
$this->fetchMessageInfo( $langCode, $messageInfo );
}
$user = User::newSystemUser( 'MediaWiki default', [ 'steal' => true ] );
if ( !$user ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
global $wgUser;
$wgUser = $user;
} elseif ( $this->hasOption( 'revrange' ) ) {
$this->dump( WikiExporter::RANGE, $textMode );
} else {
- $this->error( 'No valid action specified.', 1 );
+ $this->fatalError( 'No valid action specified.' );
}
}
public function execute() {
if ( !( $this->hasOption( 'file' ) ^ $this->hasOption( 'dump' ) ) ) {
- $this->error( "You must provide a file or dump", true );
+ $this->fatalError( "You must provide a file or dump" );
}
$this->checkOptions();
if ( $this->getOption( 'dump' ) == '-' ) {
$source = new ImportStreamSource( $this->getStdin() );
} else {
- $this->error( "Sorry, I don't support dump filenames yet. "
- . "Use - and provide it on stdin on the meantime.", true );
+ $this->fatalError( "Sorry, I don't support dump filenames yet. "
+ . "Use - and provide it on stdin on the meantime." );
}
$importer = new WikiImporter( $source, $this->getConfig() );
$wgUser = User::newFromName( $userName );
}
if ( !$wgUser ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
if ( $wgUser->isAnon() ) {
$wgUser->addToDatabase();
$title = Title::newFromText( $this->getArg() );
if ( !$title ) {
- $this->error( "Invalid title", true );
+ $this->fatalError( "Invalid title" );
}
if ( $this->hasOption( 'nocreate' ) && !$title->exists() ) {
- $this->error( "Page does not exist", true );
+ $this->fatalError( "Page does not exist" );
} elseif ( $this->hasOption( 'createonly' ) && $title->exists() ) {
- $this->error( "Page already exists", true );
+ $this->fatalError( "Page already exists" );
}
$page = WikiPage::factory( $title );
if ( $filekey === '*' ) { // all versions by name
if ( !strlen( $filename ) ) {
- $this->error( "Missing --filename parameter.", 1 );
+ $this->fatalError( "Missing --filename parameter." );
}
$afile = false;
} else { // specified version
[ 'fa_storage_group' => 'deleted', 'fa_storage_key' => $filekey ],
__METHOD__, [], $fileQuery['joins'] );
if ( !$row ) {
- $this->error( "No deleted file exists with key '$filekey'.", 1 );
+ $this->fatalError( "No deleted file exists with key '$filekey'." );
}
$filename = $row->fa_name;
$afile = ArchivedFile::newFromRow( $row );
$file = wfLocalFile( $filename );
if ( $file->exists() ) {
- $this->error( "File '$filename' is still a public file, use the delete form.\n", 1 );
+ $this->fatalError( "File '$filename' is still a public file, use the delete form.\n" );
}
$this->output( "Purging all thumbnails for file '$filename'..." );
$handle = fopen( $file, 'w' );
if ( !$handle ) {
- $this->error( "Failed to open $file for writing.\n", 1 );
+ $this->fatalError( "Failed to open $file for writing.\n" );
}
$exporter = new SiteExporter( $handle );
) {
$this->output( "Looks good!\n" );
} else {
- $this->error( 'The script finished with errors.', 1 );
+ $this->fatalError( 'The script finished with errors.' );
}
}
$repo = RepoGroup::singleton()->getLocalRepo();
if ( $repo->hasSha1Storage() ) {
- $this->error( "Local repo uses SHA-1 file storage names; aborting.", 1 );
+ $this->fatalError( "Local repo uses SHA-1 file storage names; aborting." );
}
$directory = $repo->getZonePath( 'public' );
$list = $repo->getBackend()->getFileList( [ 'dir' => $directory ] );
if ( $list === null ) {
- $this->error( "Could not get file listing.", 1 );
+ $this->fatalError( "Could not get file listing." );
}
$pathBatch = [];
if ( $this->hasOption( 'title' ) ) {
$title = Title::newFromText( $this->getOption( 'title' ) );
if ( !$title || !$title->isRedirect() ) {
- $this->error( $title->getPrefixedText() . " is not a redirect!\n", true );
+ $this->fatalError( $title->getPrefixedText() . " is not a redirect!\n" );
}
} else {
$title = null;
$row = $dbw->fetchObject( $res );
if ( is_null( $row->minrev ) ) {
- $this->error( "No revisions in search period.", true );
+ $this->fatalError( "No revisions in search period." );
}
$minRev = $row->minrev;
$numBadRevs = count( $badRevs );
if ( $numBadRevs > $numGoodRevs ) {
- $this->error(
+ $this->fatalError(
"The majority of revisions in the search interval are marked as bad.
Are you sure the offset ($offset) has the right sign? Positive means the clock
was incorrectly set forward, negative means the clock was incorrectly set back.
If the offset is right, then increase the search interval until there are enough
- good revisions to provide a majority reference.", true );
+ good revisions to provide a majority reference." );
} elseif ( $numBadRevs == 0 ) {
$this->output( "No bad revisions found.\n" );
exit( 0 );
$fileName = $this->getArg( 0 );
$inFile = fopen( $fileName, 'r' );
if ( !$inFile ) {
- $this->error( "Unable to open input file \"$fileName\"" );
- exit( 1 );
+ $this->fatalError( "Unable to open input file \"$fileName\"" );
}
} else {
$inFile = STDIN;
$fileName = $this->getOption( 'outfile' );
$outFile = fopen( $fileName, 'w' );
if ( !$outFile ) {
- $this->error( "Unable to open output file \"$fileName\"" );
- exit( 1 );
+ $this->fatalError( "Unable to open output file \"$fileName\"" );
}
} else {
$outFile = STDOUT;
if ( $extension ) {
if ( $phpfile ) {
- $this->error( "The phpfile is already specified, conflicts with --extension.", 1 );
+ $this->fatalError( "The phpfile is already specified, conflicts with --extension." );
}
$phpfile = "$IP/extensions/$extension/$extension.i18n.php";
}
$this->output( "Creating directory $jsondir.\n" );
$success = mkdir( $jsondir );
if ( !$success ) {
- $this->error( "Could not create directory $jsondir", 1 );
+ $this->fatalError( "Could not create directory $jsondir" );
}
}
if ( !is_readable( $phpfile ) ) {
- $this->error( "Error reading $phpfile", 1 );
+ $this->fatalError( "Error reading $phpfile" );
}
$messages = null;
include $phpfile;
$phpfileContents = file_get_contents( $phpfile );
if ( !isset( $messages ) ) {
- $this->error( "PHP file $phpfile does not define \$messages array", 1 );
+ $this->fatalError( "PHP file $phpfile does not define \$messages array" );
}
if ( !$messages ) {
- $this->error( "PHP file $phpfile contains an empty \$messages array. " .
- "Maybe it was already converted?", 1 );
+ $this->fatalError( "PHP file $phpfile contains an empty \$messages array. " .
+ "Maybe it was already converted?" );
}
if ( !isset( $messages['en'] ) || !is_array( $messages['en'] ) ) {
- $this->error( "PHP file $phpfile does not set language codes", 1 );
+ $this->fatalError( "PHP file $phpfile does not set language codes" );
}
foreach ( $messages as $langcode => $langmsgs ) {
FormatJson::encode( $langmsgs, "\t", FormatJson::ALL_OK ) . "\n"
);
if ( $success === false ) {
- $this->error( "FAILED to write $jsonfile", 1 );
+ $this->fatalError( "FAILED to write $jsonfile" );
}
$this->output( "$jsonfile\n" );
}
# Create directory if needed
$fspath = $this->getOption( 'fspath', getcwd() );
if ( !wfMkdirParents( $fspath, null, __METHOD__ ) ) {
- $this->error( "Can not create directory $fspath.", 1 );
+ $this->fatalError( "Can not create directory $fspath." );
}
$this->fspath = realpath( $fspath ) . DIRECTORY_SEPARATOR;
$validFormat = in_array( $format, self::$outFormats );
if ( !$validFormat ) {
- $this->error( "--format set to an unrecognized format", 0 );
+ $this->error( "--format set to an unrecognized format" );
$error_out = true;
}
$titleText = $this->getArg( 0 );
$title = Title::newFromText( $titleText );
if ( !$title ) {
- $this->error( "$titleText is not a valid title.\n", true );
+ $this->fatalError( "$titleText is not a valid title.\n" );
}
$rev = Revision::newFromTitle( $title );
if ( !$rev ) {
$titleText = $title->getPrefixedText();
- $this->error( "Page $titleText does not exist.\n", true );
+ $this->fatalError( "Page $titleText does not exist.\n" );
}
$content = $rev->getContent( $this->hasOption( 'show-private' )
? Revision::RAW
if ( $content === false ) {
$titleText = $title->getPrefixedText();
- $this->error( "Couldn't extract the text from $titleText.\n", true );
+ $this->fatalError( "Couldn't extract the text from $titleText.\n" );
}
$this->output( $content->serialize() );
}
$tmpDir = wfTempDir() . '/mw-make-repo' . mt_rand( 0, 1 << 31 );
if ( !mkdir( $tmpDir ) ) {
- $this->error( 'Unable to create temporary directory', 1 );
+ $this->fatalError( 'Unable to create temporary directory' );
}
file_put_contents( "$tmpDir/file-list", implode( "\n", $files ) );
passthru( $cmd, $ret );
if ( $ret ) {
$this->cleanupTemp( $tmpDir );
- $this->error( "Error: HHVM returned error code $ret", 1 );
+ $this->fatalError( "Error: HHVM returned error code $ret" );
}
if ( !rename( "$tmpDir/hhvm.hhbc", $this->getOption( 'output' ) ) ) {
$this->cleanupTemp( $tmpDir );
- $this->error( "Error: unable to rename output file", 1 );
+ $this->fatalError( "Error: unable to rename output file" );
}
$this->cleanupTemp( $tmpDir );
return 0;
public function execute() {
if ( wfReadOnly() ) {
- $this->error( "Wiki is in read-only mode; you'll need to disable it for import to work.", true );
+ $this->fatalError( "Wiki is in read-only mode; you'll need to disable it for import to work." );
}
$this->reportingInterval = intval( $this->getOption( 'report', 100 ) );
if ( strval( $ns ) === $namespace && $wgContLang->getNsText( $ns ) !== false ) {
return $ns;
}
- $this->error( "Unknown namespace text / index specified: $namespace", true );
+ $this->fatalError( "Unknown namespace text / index specified: $namespace" );
}
/**
$statusRootPage = $importer->setTargetRootPage( $this->getOption( 'rootpage' ) );
if ( !$statusRootPage->isGood() ) {
// Die here so that it doesn't print "Done!"
- $this->error( $statusRootPage->getMessage()->text(), 1 );
+ $this->fatalError( $statusRootPage->getMessage()->text() );
return false;
}
}
# Check Protection
if ( $this->hasOption( 'protect' ) && $this->hasOption( 'unprotect' ) ) {
- $this->error( "Cannot specify both protect and unprotect. Only 1 is allowed.\n", 1 );
+ $this->fatalError( "Cannot specify both protect and unprotect. Only 1 is allowed.\n" );
}
if ( $this->hasOption( 'protect' ) && trim( $this->getOption( 'protect' ) ) ) {
- $this->error( "You must specify a protection option.\n", 1 );
+ $this->fatalError( "You must specify a protection option.\n" );
}
# Prepare the list of allowed extensions
if ( $commentFile !== null ) {
$comment = file_get_contents( $commentFile );
if ( $comment === false || $comment === null ) {
- $this->error( "failed to read comment file: {$commentFile}\n", 1 );
+ $this->fatalError( "failed to read comment file: {$commentFile}\n" );
}
} else {
$comment = $this->getOption( 'comment', 'Importing file' );
$files[$filename] = file_get_contents( $filename );
}
if ( !$found ) {
- $this->error( "Fatal error: The file '$arg' does not exist!", 1 );
+ $this->fatalError( "Fatal error: The file '$arg' does not exist!" );
}
}
};
}
if ( !$user ) {
- $this->error( "Invalid username\n", true );
+ $this->fatalError( "Invalid username\n" );
}
if ( $user->isAnon() ) {
$user->addToDatabase();
$this->output( "Done! $successCount succeeded, $skipCount skipped.\n" );
if ( $exit ) {
- $this->error( "Import failed with $failCount failed pages.\n", $exit );
+ $this->fatalError( "Import failed with $failCount failed pages.\n", $exit );
}
}
}
$dbpass = file_get_contents( $dbpassfile ); // returns false on failure
MediaWiki\restoreWarnings();
if ( $dbpass === false ) {
- $this->error( "Couldn't open $dbpassfile", true );
+ $this->fatalError( "Couldn't open $dbpassfile" );
}
$this->mOptions['dbpass'] = trim( $dbpass, "\r\n" );
}
$pass = file_get_contents( $passfile ); // returns false on failure
MediaWiki\restoreWarnings();
if ( $pass === false ) {
- $this->error( "Couldn't open $passfile", true );
+ $this->fatalError( "Couldn't open $passfile" );
}
$this->mOptions['pass'] = trim( $pass, "\r\n" );
} elseif ( $this->getOption( 'pass' ) === null ) {
- $this->error( 'You need to provide the option "pass" or "passfile"', true );
+ $this->fatalError( 'You need to provide the option "pass" or "passfile"' );
}
}
$file = $this->getOption( 'file' );
if ( $username === null && $file === null ) {
- $this->error( 'Either --user or --file is required', 1 );
+ $this->fatalError( 'Either --user or --file is required' );
} elseif ( $username !== null && $file !== null ) {
- $this->error( 'Cannot use both --user and --file', 1 );
+ $this->fatalError( 'Cannot use both --user and --file' );
}
if ( $username !== null ) {
$usernames = is_readable( $file ) ?
file( $file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ) : false;
if ( $usernames === false ) {
- $this->error( "Could not open $file", 2 );
+ $this->fatalError( "Could not open $file", 2 );
}
}
$error .= "* $ucdallURL\n";
}
- $this->error( $error );
- exit( 1 );
+ $this->fatalError( $error );
}
$debugOutFileName = $this->getOption( 'debug-output' );
if ( $debugOutFileName ) {
$this->debugOutFile = fopen( $debugOutFileName, 'w' );
if ( !$this->debugOutFile ) {
- $this->error( "Unable to open debug output file for writing" );
- exit( 1 );
+ $this->fatalError( "Unable to open debug output file for writing" );
}
}
$this->loadUcd();
function generateFirstChars() {
$file = fopen( "{$this->dataDir}/allkeys.txt", 'r' );
if ( !$file ) {
- $this->error( "Unable to open allkeys.txt" );
- exit( 1 );
+ $this->fatalError( "Unable to open allkeys.txt" );
}
global $IP;
$outFile = fopen( "$IP/serialized/first-letters-root.ser", 'w' );
if ( !$outFile ) {
- $this->error( "Unable to open output file first-letters-root.ser" );
- exit( 1 );
+ $this->fatalError( "Unable to open output file first-letters-root.ser" );
}
$goodTertiaryChars = [];
if ( !$this->hasOption( 'unicode-data-file' ) ) {
$dataFile = 'UnicodeData.txt';
if ( !file_exists( $dataFile ) ) {
- $this->error( "Unable to find UnicodeData.txt. Please specify " .
+ $this->fatalError( "Unable to find UnicodeData.txt. Please specify " .
"its location with --unicode-data-file=<FILE>" );
- exit( 1 );
}
} else {
$dataFile = $this->getOption( 'unicode-data-file' );
if ( !file_exists( $dataFile ) ) {
- $this->error( 'Unable to find the specified data file.' );
- exit( 1 );
+ $this->fatalError( 'Unable to find the specified data file.' );
}
}
$file = fopen( $dataFile, 'r' );
if ( !$file ) {
- $this->error( 'Unable to open the data file.' );
- exit( 1 );
+ $this->fatalError( 'Unable to open the data file.' );
}
// For the file format, see http://www.unicode.org/reports/tr44/
public function execute() {
if ( !function_exists( 'memory_get_usage' ) ) {
- $this->error( "You must compile PHP with --enable-memory-limit", true );
+ $this->fatalError( "You must compile PHP with --enable-memory-limit" );
}
$langtool = new Languages();
public function execute() {
$user = User::newFromName( $this->getOption( 'user' ) );
if ( !$user->getId() ) {
- $this->error( "No such user exists.", 1 );
+ $this->fatalError( "No such user exists." );
}
$count = $this->getOption( 'count' );
} elseif ( $action === 'repush-abandoned' ) {
$this->repushAbandoned( $queue );
} else {
- $this->error( "Invalid action '$action'.", 1 );
+ $this->fatalError( "Invalid action '$action'." );
}
}
$iterations = $this->getOption( 'i', 100 );
if ( $cache ) {
if ( !isset( $wgObjectCaches[$cache] ) ) {
- $this->error( "MediaWiki isn't configured with a cache named '$cache'", 1 );
+ $this->fatalError( "MediaWiki isn't configured with a cache named '$cache'" );
}
$servers = $wgObjectCaches[$cache]['servers'];
} elseif ( $this->hasArg() ) {
} elseif ( isset( $wgObjectCaches[$wgMainCacheType]['servers'] ) ) {
$servers = $wgObjectCaches[$wgMainCacheType]['servers'];
} else {
- $this->error( "MediaWiki isn't configured for Memcached usage", 1 );
+ $this->fatalError( "MediaWiki isn't configured for Memcached usage" );
}
# find out the longest server string to nicely align output later on
&& !$this->hasOption( 'list-file' )
&& !$this->hasOption( 'extensions-dir' )
) {
- $this->error( "Either --list-file or --extensions-dir must be provided if " .
- "\$wgExtensionEntryPointListFiles is not set", 1 );
+ $this->fatalError( "Either --list-file or --extensions-dir must be provided if " .
+ "\$wgExtensionEntryPointListFiles is not set" );
}
$mmfl = [ 'setupFiles' => [] ];
public function execute() {
$oldLayout = $this->getOption( 'oldlayout' );
if ( !in_array( $oldLayout, [ 'name', 'sha1' ] ) ) {
- $this->error( "Invalid old layout.", 1 );
+ $this->fatalError( "Invalid old layout." );
}
$newLayout = $this->getOption( 'newlayout' );
if ( !in_array( $newLayout, [ 'name', 'sha1' ] ) ) {
- $this->error( "Invalid new layout.", 1 );
+ $this->fatalError( "Invalid new layout." );
}
$since = $this->getOption( 'since' );
$end = $dbw->selectField( 'user_groups', 'MAX(ug_user)',
[ 'ug_group' => $oldGroup ], __FUNCTION__ );
if ( $start === null ) {
- $this->error( "Nothing to do - no users in the '$oldGroup' group", true );
+ $this->fatalError( "Nothing to do - no users in the '$oldGroup' group" );
}
# Do remaining chunk
$end += $batchSize - 1;
public function execute() {
if ( !count( $this->mArgs ) ) {
- $this->error( "minify.php: At least one input file must be specified." );
- exit( 1 );
+ $this->fatalError( "minify.php: At least one input file must be specified." );
}
if ( $this->hasOption( 'outfile' ) ) {
if ( count( $this->mArgs ) > 1 ) {
- $this->error( '--outfile may only be used with a single input file.' );
- exit( 1 );
+ $this->fatalError( '--outfile may only be used with a single input file.' );
}
// Minify one file
}
if ( !file_exists( $inPath ) ) {
- $this->error( "File does not exist: $arg", true );
+ $this->fatalError( "File does not exist: $arg" );
}
$extension = $this->getExtension( $inName );
public function getExtension( $fileName ) {
$dotPos = strrpos( $fileName, '.' );
if ( $dotPos === false ) {
- $this->error( "No file extension, cannot determine type: $fileName" );
- exit( 1 );
+ $this->fatalError( "No file extension, cannot determine type: $fileName" );
}
return substr( $fileName, $dotPos + 1 );
$inText = file_get_contents( $inPath );
if ( $inText === false ) {
- $this->error( "Unable to open file $inPath for reading." );
- exit( 1 );
+ $this->fatalError( "Unable to open file $inPath for reading." );
}
$outFile = fopen( $outPath, 'w' );
if ( !$outFile ) {
- $this->error( "Unable to open file $outPath for writing." );
- exit( 1 );
+ $this->fatalError( "Unable to open file $outPath for writing." );
}
switch ( $extension ) {
# Setup
if ( !$file ) {
- $this->error( "Unable to read file, exiting", true );
+ $this->fatalError( "Unable to read file, exiting" );
}
if ( $user === false ) {
$wgUser = User::newSystemUser( 'Move page script', [ 'steal' => true ] );
$wgUser = User::newFromName( $user );
}
if ( !$wgUser ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
# Setup complete, now start
$tmpFile = tempnam( wfTempDir(), 'MWDocGen-' );
if ( file_put_contents( $tmpFile, $conf ) === false ) {
- $this->error( "Could not write doxygen configuration to file $tmpFile\n",
- /** exit code: */ 1 );
+ $this->fatalError( "Could not write doxygen configuration to file $tmpFile\n" );
}
$command = $this->doxygen . ' ' . $tmpFile;
);
if ( $exitcode !== 0 ) {
- $this->error( "Something went wrong (exit: $exitcode)\n",
- $exitcode );
+ $this->fatalError( "Something went wrong (exit: $exitcode)\n", $exitcode );
}
}
}
$code = 1;
}
$this->output( $text );
- $this->error( '', $code );
+ exit( $code );
}
}
$ns = $this->getOption( 'ns' );
if ( !ctype_digit( $ns ) && $ns !== 'all' ) {
- $this->error( 'Invalid namespace', 1 );
+ $this->fatalError( 'Invalid namespace' );
}
$ns = $ns === 'all' ? 'all' : (int)$ns;
$table = $this->getOption( 'table' );
$this->populatePage( $dbw, $ns );
break;
default:
- $this->error( "Invalid table name: $table", 1 );
+ $this->fatalError( "Invalid table name: $table" );
}
}
__METHOD__
);
if ( !$res ) {
- $this->error( "No such file: $file", true );
-
- return false;
+ $this->fatalError( "No such file: $file" );
}
$this->output( "Populating img_sha1 field for specified files\n" );
} else {
public function doDBUpdates() {
$dbw = $this->getDB( DB_MASTER );
if ( !$dbw->tableExists( 'revision' ) ) {
- $this->error( "revision table does not exist", true );
+ $this->fatalError( "revision table does not exist" );
} elseif ( !$dbw->tableExists( 'archive' ) ) {
- $this->error( "archive table does not exist", true );
+ $this->fatalError( "archive table does not exist" );
} elseif ( !$dbw->fieldExists( 'revision', 'rev_len', __METHOD__ ) ) {
$this->output( "rev_len column does not exist\n\n", true );
$db = $this->getDB( DB_MASTER );
if ( !$db->tableExists( 'revision' ) ) {
- $this->error( "revision table does not exist", true );
+ $this->fatalError( "revision table does not exist" );
} elseif ( !$db->tableExists( 'archive' ) ) {
- $this->error( "archive table does not exist", true );
+ $this->fatalError( "archive table does not exist" );
} elseif ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) {
$this->output( "rev_sha1 column does not exist\n\n", true );
$user = User::newFromName( $userName );
}
if ( !$user ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
// @todo FIXME: This is reset 7 lines down.
$t = Title::newFromText( $this->getArg() );
if ( !$t ) {
- $this->error( "Invalid title", true );
+ $this->fatalError( "Invalid title" );
}
$restrictions = [];
global $wgUseFileCache, $wgFileCacheDirectory;
if ( !$wgUseFileCache ) {
- $this->error( "Nothing to do -- \$wgUseFileCache is disabled.", true );
+ $this->fatalError( "Nothing to do -- \$wgUseFileCache is disabled." );
}
$age = $this->getOption( 'agedays' );
if ( !ctype_digit( $age ) ) {
- $this->error( "Non-integer 'age' parameter given.", true );
+ $this->fatalError( "Non-integer 'age' parameter given." );
}
// Delete items with a TS older than this
$this->minSurviveTimestamp = time() - ( 86400 * $age );
$dir = $wgFileCacheDirectory;
if ( !is_dir( $dir ) ) {
- $this->error( "Nothing to do -- \$wgFileCacheDirectory directory not found.", true );
+ $this->fatalError( "Nothing to do -- \$wgFileCacheDirectory directory not found." );
}
$subDir = $this->getOption( 'subdir' );
if ( $subDir !== null ) {
if ( !is_dir( "$dir/$subDir" ) ) {
- $this->error( "The specified subdirectory `$subDir` does not exist.", true );
+ $this->fatalError( "The specified subdirectory `$subDir` does not exist." );
}
$this->output( "Pruning `$dir/$subDir` directory...\n" );
$this->prune_directory( "$dir/$subDir", 'report' );
} elseif ( $inputAge !== null ) {
$date = wfTimestamp( TS_MW, time() + $wgParserCacheExpireTime - intval( $inputAge ) );
} else {
- $this->error( "Must specify either --expiredate or --age", 1 );
+ $this->fatalError( "Must specify either --expiredate or --age" );
return;
}
$this->usleep = 1e3 * $this->getOption( 'msleep', 0 );
$pc = MediaWikiServices::getInstance()->getParserCache()->getCacheStorage();
$success = $pc->deleteObjectsExpiringBefore( $date, [ $this, 'showProgressAndWait' ] );
if ( !$success ) {
- $this->error( "\nCannot purge this kind of parser cache.", 1 );
+ $this->fatalError( "\nCannot purge this kind of parser cache." );
}
$this->showProgressAndWait( 100 );
$this->output( "\nDone\n" );
} else {
$user = User::newFromName( $username );
if ( !$user ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
}
$user->load();
global $wgRequestTime;
if ( !$this->enabled ) {
- $this->error( "Nothing to do -- \$wgUseFileCache is disabled.", true );
+ $this->fatalError( "Nothing to do -- \$wgUseFileCache is disabled." );
}
$start = $this->getOption( 'start', "0" );
if ( !ctype_digit( $start ) ) {
- $this->error( "Invalid value for start parameter.", true );
+ $this->fatalError( "Invalid value for start parameter." );
}
$start = intval( $start );
$end = $this->getOption( 'end', "0" );
if ( !ctype_digit( $end ) ) {
- $this->error( "Invalid value for end parameter.", true );
+ $this->fatalError( "Invalid value for end parameter." );
}
$end = intval( $end );
? $end
: $dbr->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
if ( !$start ) {
- $this->error( "Nothing to do.", true );
+ $this->fatalError( "Nothing to do." );
}
$_SERVER['HTTP_ACCEPT_ENCODING'] = 'bgzip'; // hack, no real client
explode( ',', $this->getOption( 'lang' ) ) );
# Bailed out if nothing is left
if ( count( $codes ) == 0 ) {
- $this->error( 'None of the languages specified exists.', 1 );
+ $this->fatalError( 'None of the languages specified exists.' );
}
} else {
# By default get all languages
$jsonFile = $this->getConfig()->get( 'SitesCacheFile' );
if ( $jsonFile === false ) {
- $this->error( 'Error: No file set in configuration for SitesCacheFile.', 1 );
+ $this->fatalError( 'Error: No file set in configuration for SitesCacheFile.' );
}
}
( $this->hasOption( 'from' ) && !$this->hasOption( 'to' ) ) ||
( !$this->hasOption( 'from' ) && $this->hasOption( 'to' ) )
) {
- $this->error( "Both 'from' and 'to' must be given, or neither", 1 );
+ $this->fatalError( "Both 'from' and 'to' must be given, or neither" );
}
$this->rebuildRecentChangesTablePass1();
// Shouldn't be needed for Postgres
$this->db = $this->getDB( DB_MASTER );
if ( $this->db->getType() == 'postgres' ) {
- $this->error( "This script is not needed when using Postgres.\n", true );
+ $this->fatalError( "This script is not needed when using Postgres.\n" );
}
if ( $this->db->getType() == 'sqlite' ) {
if ( !DatabaseSqlite::getFulltextSearchModule() ) {
- $this->error( "Your version of SQLite module for PHP doesn't "
- . "support full-text search (FTS3).\n", true );
+ $this->fatalError( "Your version of SQLite module for PHP doesn't "
+ . "support full-text search (FTS3).\n" );
}
if ( !$this->db->checkForEnabledSearch() ) {
- $this->error( "Your database schema is not configured for "
- . "full-text search support. Run update.php.\n", true );
+ $this->fatalError( "Your database schema is not configured for "
+ . "full-text search support. Run update.php.\n" );
}
}
public function execute() {
$this->mode = $this->getOption( 'mode' );
if ( !in_array( $this->mode, [ 'pages', 'subcats', 'files' ] ) ) {
- $this->error( 'Please specify a valid mode: one of "pages", "subcats" or "files".', 1 );
+ $this->fatalError( 'Please specify a valid mode: one of "pages", "subcats" or "files".' );
}
$this->minimumId = intval( $this->getOption( 'begin', 0 ) );
$dbw = $this->getDB( DB_MASTER );
$batchSize = $this->getBatchSize();
if ( $batchSize <= 0 ) {
- $this->error( "Batch size is too low...", 12 );
+ $this->fatalError( "Batch size is too low...", 12 );
}
$repo = RepoGroup::singleton()->getLocalRepo();
}
if ( $brokenOnly && $force ) {
- $this->error( 'Cannot use --broken-only and --force together. ', 2 );
+ $this->fatalError( 'Cannot use --broken-only and --force together. ', 2 );
}
}
}
if ( ( $category = $this->getOption( 'category', false ) ) !== false ) {
$title = Title::makeTitleSafe( NS_CATEGORY, $category );
if ( !$title ) {
- $this->error( "'$category' is an invalid category name!\n", true );
+ $this->fatalError( "'$category' is an invalid category name!\n" );
}
$this->refreshCategory( $title );
} elseif ( ( $category = $this->getOption( 'tracking-category', false ) ) !== false ) {
if ( isset( $cats[$categoryKey] ) ) {
return $cats[$categoryKey]['cats'];
}
- $this->error( "Unknown tracking category {$categoryKey}\n", true );
+ $this->fatalError( "Unknown tracking category {$categoryKey}\n" );
}
}
}
$touched = $this->getOption( 'ignore-touched', "1" );
if ( !ctype_digit( $touched ) ) {
- $this->error( "Please put a valid positive integer on the --ignore-touched parameter.", true );
+ $this->fatalError( "Please put a valid positive integer on the --ignore-touched parameter." );
}
$touchedSeconds = 86400 * $touched;
foreach ( $res as $row ) {
}
if ( $old === false || $new === false ) {
- $this->error( "Invalid prefix!", true );
+ $this->fatalError( "Invalid prefix!" );
}
if ( $old === $new ) {
$this->output( "Same prefix. Nothing to rename!\n", true );
$user = User::newFromName( $userName );
}
if ( !$user || !$user->getId() || !$user->loadFromId() ) {
- $this->error( "Error: user '$userName' does not exist\n", 1 );
+ $this->fatalError( "Error: user '$userName' does not exist\n" );
}
$email = $this->getArg( 1 );
if ( !Sanitizer::validateEmail( $email ) ) {
- $this->error( "Error: email '$email' is not valid\n", 1 );
+ $this->fatalError( "Error: email '$email' is not valid\n" );
}
// Code from https://wikitech.wikimedia.org/wiki/Password_reset
$user = $this->getOption( 'user' );
$username = User::isIP( $user ) ? $user : User::getCanonicalName( $user );
if ( !$username ) {
- $this->error( 'Invalid username', true );
+ $this->fatalError( 'Invalid username' );
}
$bot = $this->hasOption( 'bot' );
if ( $this->hasOption( 'procs' ) ) {
$procs = intval( $this->getOption( 'procs' ) );
if ( $procs < 1 || $procs > 1000 ) {
- $this->error( "Invalid argument to --procs", true );
+ $this->fatalError( "Invalid argument to --procs" );
} elseif ( $procs != 1 ) {
$fc = new ForkController( $procs );
if ( $fc->start() != 'child' ) {
public function execute() {
if ( !class_exists( \Psy\Shell::class ) ) {
- $this->error( 'PsySH not found. Please run composer with the --dev option.', 1 );
+ $this->fatalError( 'PsySH not found. Please run composer with the --dev option.' );
}
$traverser = new \PhpParser\NodeTraverser();
}
}
if ( $index === null ) {
- $this->error( "No replica DB server configured with the name '$replicaDB'.", 1 );
+ $this->fatalError( "No replica DB server configured with the name '$replicaDB'." );
}
} else {
$index = DB_MASTER;
/** @var IDatabase $db DB handle for the appropriate cluster/wiki */
$db = $lb->getConnection( $index, [], $wiki );
if ( $replicaDB != '' && $db->getLBInfo( 'master' ) !== null ) {
- $this->error( "The server selected ({$db->getServer()}) is not a replica DB.", 1 );
+ $this->fatalError( "The server selected ({$db->getServer()}) is not a replica DB." );
}
if ( $index === DB_MASTER ) {
if ( $this->hasArg( 0 ) ) {
$file = fopen( $this->getArg( 0 ), 'r' );
if ( !$file ) {
- $this->error( "Unable to open input file", true );
+ $this->fatalError( "Unable to open input file" );
}
$error = $db->sourceStream( $file, null, [ $this, 'sqlPrintResult' ] );
if ( $error !== true ) {
- $this->error( $error, true );
+ $this->fatalError( $error );
} else {
exit( 0 );
}
$res = $db->query( $line );
$this->sqlPrintResult( $res, $db );
} catch ( DBQueryError $e ) {
- $this->error( $e, $dieOnError );
+ if ( $dieOnError ) {
+ $this->fatalError( $e );
+ } else {
+ $this->error( $e );
+ }
}
}
private function vacuum() {
$prevSize = filesize( $this->db->getDbFilePath() );
if ( $prevSize == 0 ) {
- $this->error( "Can't vacuum an empty database.\n", true );
+ $this->fatalError( "Can't vacuum an empty database.\n" );
}
$this->output( 'VACUUM: ' );
// This is a known bug from 2004
// It's safe to just erase the old_flags field
if ( $fix ) {
- $this->error( 'fixed', "Warning: old_flags set to 0", $id );
+ $this->addError( 'fixed', "Warning: old_flags set to 0", $id );
$dbw = wfGetDB( DB_MASTER );
$dbw->ping();
$dbw->update( 'text', [ 'old_flags' => '' ],
[ 'old_id' => $id ], __METHOD__ );
echo "Fixed\n";
} else {
- $this->error( 'fixable', "Warning: old_flags set to 0", $id );
+ $this->addError( 'fixable', "Warning: old_flags set to 0", $id );
}
} elseif ( count( array_diff( $flagArray, $knownFlags ) ) ) {
- $this->error( 'unfixable', "Error: invalid flags field \"$flags\"", $id );
+ $this->addError( 'unfixable', "Error: invalid flags field \"$flags\"", $id );
}
}
$dbr->freeResult( $res );
// Output errors for any missing text rows
foreach ( $missingTextRows as $oldId => $revId ) {
- $this->error( 'restore revision', "Error: missing text row", $oldId );
+ $this->addError( 'restore revision', "Error: missing text row", $oldId );
}
// Verify external revisions
foreach ( $res as $row ) {
$urlParts = explode( '://', $row->old_text, 2 );
if ( count( $urlParts ) !== 2 || $urlParts[1] == '' ) {
- $this->error( 'restore text', "Error: invalid URL \"{$row->old_text}\"", $row->old_id );
+ $this->addError( 'restore text', "Error: invalid URL \"{$row->old_text}\"", $row->old_id );
continue;
}
list( $proto, ) = $urlParts;
if ( $proto != 'DB' ) {
- $this->error( 'restore text', "Error: invalid external protocol \"$proto\"", $row->old_id );
+ $this->addError(
+ 'restore text',
+ "Error: invalid external protocol \"$proto\"",
+ $row->old_id );
continue;
}
$path = explode( '/', $row->old_text );
$extDb->freeResult( $res );
// Print errors for missing blobs rows
foreach ( $xBlobIds as $blobId => $oldId ) {
- $this->error( 'restore text', "Error: missing target $blobId for one-part ES URL", $oldId );
+ $this->addError(
+ 'restore text',
+ "Error: missing target $blobId for one-part ES URL",
+ $oldId );
}
}
}
$oldId = $row->old_id;
$matches = [];
if ( !preg_match( '/^O:(\d+):"(\w+)"/', $row->header, $matches ) ) {
- $this->error( 'restore text', "Error: invalid object header", $oldId );
+ $this->addError( 'restore text', "Error: invalid object header", $oldId );
continue;
}
$className = strtolower( $matches[2] );
if ( strlen( $className ) != $matches[1] ) {
- $this->error(
+ $this->addError(
'restore text',
"Error: invalid object header, wrong class name length",
$oldId
case 'historyblobstub':
case 'historyblobcurstub':
if ( strlen( $row->header ) == $headerLength ) {
- $this->error( 'unfixable', "Error: overlong stub header", $oldId );
+ $this->addError( 'unfixable', "Error: overlong stub header", $oldId );
continue;
}
$stubObj = unserialize( $row->header );
if ( !is_object( $stubObj ) ) {
- $this->error( 'restore text', "Error: unable to unserialize stub object", $oldId );
+ $this->addError( 'restore text', "Error: unable to unserialize stub object", $oldId );
continue;
}
if ( $className == 'historyblobstub' ) {
}
break;
default:
- $this->error( 'unfixable', "Error: unrecognised object class \"$className\"", $oldId );
+ $this->addError( 'unfixable', "Error: unrecognised object class \"$className\"", $oldId );
}
}
$dbr->freeResult( $res );
if ( in_array( 'object', $flags ) ) {
$urlParts = explode( '/', $row->header );
if ( $urlParts[0] != 'DB:' ) {
- $this->error(
+ $this->addError(
'unfixable',
"Error: unrecognised external storage type \"{$urlParts[0]}",
$row->old_id
);
}
} else {
- $this->error(
+ $this->addError(
'unfixable',
"Error: invalid flags \"{$row->old_flags}\" on concat bulk row {$row->old_id}",
$concatBlobs[$row->old_id] );
substr( $row->header, 0, strlen( self::CONCAT_HEADER ) ),
self::CONCAT_HEADER
) ) {
- $this->error(
+ $this->addError(
'restore text',
"Error: Incorrect object header for concat bulk row {$row->old_id}",
$concatBlobs[$row->old_id]
}
}
- function error( $type, $msg, $ids ) {
+ function addError( $type, $msg, $ids ) {
if ( is_array( $ids ) && count( $ids ) == 1 ) {
$ids = reset( $ids );
}
[ 'blob_id IN( ' . implode( ',', $blobIds ) . ')' ], __METHOD__ );
foreach ( $res as $row ) {
if ( strcasecmp( $row->header, self::CONCAT_HEADER ) ) {
- $this->error(
+ $this->addError(
'restore text',
"Error: invalid header on target $cluster/{$row->blob_id} of two-part ES URL",
$oldIds[$row->blob_id]
// Print errors for missing blobs rows
foreach ( $oldIds as $blobId => $oldIds2 ) {
- $this->error(
+ $this->addError(
'restore text',
"Error: missing target $cluster/$blobId for two-part ES URL",
$oldIds2
public function execute() {
global $wgDBname;
if ( !function_exists( "gzdeflate" ) ) {
- $this->error( "You must enable zlib support in PHP to compress old revisions!\n" .
- "Please see http://www.php.net/manual/en/ref.zlib.php\n", true );
+ $this->fatalError( "You must enable zlib support in PHP to compress old revisions!\n" .
+ "Please see http://www.php.net/manual/en/ref.zlib.php\n" );
}
$type = $this->getOption( 'type', 'concat' );
[ 'old_id=rev_text_id', 'rev_id' => $this->getArg() ]
);
if ( !$row ) {
- $this->error( "Row not found", true );
+ $this->fatalError( "Row not found" );
}
$flags = explode( ',', $row->old_flags );
public function execute() {
$dbr = $this->getDB( DB_REPLICA );
if ( !$dbr->tableExists( 'blob_orphans' ) ) {
- $this->error( "blob_orphans doesn't seem to exist, need to run trackBlobs.php first", true );
+ $this->fatalError( "blob_orphans doesn't seem to exist, need to run trackBlobs.php first" );
}
$res = $dbr->select( 'blob_orphans', '*', false, __METHOD__ );
if ( $this->hasOption( 'posdump' ) ) {
// Just dump the current position into the specified position dir
if ( !$this->hasOption( 'posdir' ) ) {
- $this->error( "Param posdir required!", 1 );
+ $this->fatalError( "Param posdir required!" );
}
if ( $this->hasOption( 'postime' ) ) {
$id = (int)$src->getJournal()->getPositionAtTime( $this->getOption( 'postime' ) );
}
if ( !$this->hasOption( 'dst' ) ) {
- $this->error( "Param dst required!", 1 );
+ $this->fatalError( "Param dst required!" );
}
$dst = FileBackendGroup::singleton()->get( $this->getOption( 'dst' ) );
$first = true; // first batch
if ( $start > $end ) { // sanity
- $this->error( "Error: given starting ID greater than ending ID.", 1 );
+ $this->fatalError( "Error: given starting ID greater than ending ID." );
}
$next = null;
$title = Title::newFromText( $pageName );
if ( !$title ) {
- $this->error( "Invalid title", true );
+ $this->fatalError( "Invalid title" );
}
if ( $user === false ) {
$wgUser = User::newSystemUser( 'Command line script', [ 'steal' => true ] );
$wgUser = User::newFromName( $user );
}
if ( !$wgUser ) {
- $this->error( "Invalid username", true );
+ $this->fatalError( "Invalid username" );
}
$archive = new PageArchive( $title, RequestContext::getMain()->getConfig() );
$this->output( "Undeleting " . $title->getPrefixedDBkey() . '...' );
list( $pcreVersion ) = explode( ' ', PCRE_VERSION, 2 );
if ( version_compare( $pcreVersion, $minimumPcreVersion, '<' ) ) {
- $this->error(
+ $this->fatalError(
"PCRE $minimumPcreVersion or later is required.\n" .
"Your PHP binary is linked with PCRE $pcreVersion.\n\n" .
"More information:\n" .
"https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE\n\n" .
- "ABORTING.\n",
- true );
+ "ABORTING.\n" );
}
$test = new PhpXmlBugTester();
if ( !$test->ok ) {
- $this->error(
+ $this->fatalError(
"Your system has a combination of PHP and libxml2 versions that is buggy\n" .
"and can cause hidden data corruption in MediaWiki and other web apps.\n" .
"Upgrade to libxml2 2.7.3 or later.\n" .
- "ABORTING (see https://bugs.php.net/bug.php?id=45996).\n",
- true );
+ "ABORTING (see https://bugs.php.net/bug.php?id=45996).\n" );
}
}
|| $this->hasOption( 'schema' )
|| $this->hasOption( 'noschema' ) )
) {
- $this->error( "Do not run update.php on this wiki. If you're seeing this you should\n"
+ $this->fatalError( "Do not run update.php on this wiki. If you're seeing this you should\n"
. "probably ask for some help in performing your schema updates or use\n"
. "the --noschema and --schema options to get an SQL file for someone\n"
. "else to inspect and run.\n\n"
- . "If you know what you are doing, you can continue with --force\n", true );
+ . "If you know what you are doing, you can continue with --force\n" );
}
$this->fileHandle = null;
if ( substr( $this->getOption( 'schema' ), 0, 2 ) === "--" ) {
- $this->error( "The --schema option requires a file as an argument.\n", true );
+ $this->fatalError( "The --schema option requires a file as an argument.\n" );
} elseif ( $this->hasOption( 'schema' ) ) {
$file = $this->getOption( 'schema' );
$this->fileHandle = fopen( $file, "w" );
if ( $this->fileHandle === false ) {
$err = error_get_last();
- $this->error( "Problem opening the schema file for writing: $file\n\t{$err['message']}", true );
+ $this->fatalError( "Problem opening the schema file for writing: $file\n\t{$err['message']}" );
}
}
if ( !$status->isOK() ) {
// This might output some wikitext like <strong> but it should be comprehensible
$text = $status->getWikiText();
- $this->error( $text, 1 );
+ $this->fatalError( $text );
}
$this->output( "Going to run database updates for " . wfWikiID() . "\n" );
$dbw = $this->getDB( DB_MASTER );
if ( $dbw->getType() !== 'mysql' ) {
- $this->error( "This change is only needed on MySQL, quitting.\n", true );
+ $this->fatalError( "This change is only needed on MySQL, quitting.\n" );
}
$res = $this->findRows( $dbw );
public function execute() {
$filename = $this->getArg( 0 );
if ( !is_readable( $filename ) ) {
- $this->error( "Error: Unable to read $filename", 1 );
+ $this->fatalError( "Error: Unable to read $filename" );
}
$json = FormatJson::decode( file_get_contents( $filename ), true );
if ( $json === null ) {
- $this->error( "Error: Invalid JSON", 1 );
+ $this->fatalError( "Error: Invalid JSON" );
}
if ( !isset( $json['manifest_version'] ) ) {
$db = $this->getDB( DB_MASTER );
$batchSize = $this->getBatchSize();
if ( !$db->tableExists( 'page_restrictions' ) ) {
- $this->error( "page_restrictions table does not exist", true );
+ $this->fatalError( "page_restrictions table does not exist" );
}
$start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
if ( !$start ) {
- $this->error( "Nothing to do.", true );
+ $this->fatalError( "Nothing to do." );
}
$end = $db->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
$queryPage = $specialObj;
} else {
$class = get_class( $specialObj );
- $this->error( "$class is not an instance of QueryPage.\n", 1 );
+ $this->fatalError( "$class is not an instance of QueryPage.\n" );
die;
}
// Get the options and update stats
if ( $option ) {
if ( !array_key_exists( $option, $defaultOptions ) ) {
- $this->error( "Invalid user option. Use --list to see valid choices\n", 1 );
+ $this->fatalError( "Invalid user option. Use --list to see valid choices\n" );
}
$userValue = $user->getOption( $option );
}
public function execute() {
$validator = new ExtensionJsonValidator( function ( $msg ) {
- $this->error( $msg, 1 );
+ $this->fatalError( $msg );
} );
$validator->checkDependencies();
$path = $this->getArg( 0 );
$validator->validate( $path );
$this->output( "$path validates against the schema!\n" );
} catch ( ExtensionJsonValidationError $e ) {
- $this->error( $e->getMessage(), 1 );
+ $this->fatalError( $e->getMessage() );
}
}
}
public function execute() {
$title = Title::newFromText( $this->getArg() );
if ( !$title ) {
- $this->error( "Invalid title", true );
+ $this->fatalError( "Invalid title" );
}
$page = WikiPage::factory( $title );
$content = $page->getContent( Revision::RAW );
if ( !$content ) {
- $this->error( "Page has no content", true );
+ $this->fatalError( "Page has no content" );
}
if ( !$content instanceof TextContent ) {
- $this->error( "Non-text content models not supported", true );
+ $this->fatalError( "Non-text content models not supported" );
}
$this->output( $content->getNativeData() );
// Check that type exists and is a layered type
if ( !isset( $typeInfo[$layeredType] ) ) {
- $this->error( 'Undefined password type', true );
+ $this->fatalError( 'Undefined password type' );
}
$passObj = $passwordFactory->newFromType( $layeredType );
if ( !$passObj instanceof LayeredParameterizedPassword ) {
- $this->error( 'Layered parameterized password type must be used.', true );
+ $this->fatalError( 'Layered parameterized password type must be used.' );
}
// Extract the first layer type
"private": true,
"scripts": {
"test": "grunt test",
+ "qunit": "grunt qunit",
"doc": "jsduck",
"postdoc": "grunt copy:jsduck",
"selenium": "killall -0 chromedriver 2>/dev/null || chromedriver --url-base=/wd/hub --port=4444 & grunt webdriver:test; killall chromedriver"
],
],
'mediawiki.special' => [
- 'styles' => 'resources/src/mediawiki.special/mediawiki.special.css',
+ 'styles' => [
+ 'resources/src/mediawiki.special/mediawiki.special.css',
+ 'resources/src/mediawiki.special/mediawiki.special.userrights.css',
+ ],
'targets' => [ 'desktop', 'mobile' ],
],
'mediawiki.special.apisandbox.styles' => [
'api-help-param-integer-minmax',
'api-help-param-multi-separate',
'api-help-param-multi-max',
+ 'api-help-param-maxbytes',
+ 'api-help-param-maxchars',
'apisandbox-submit-invalid-fields-title',
'apisandbox-submit-invalid-fields-message',
'apisandbox-results',
'mediawiki.notification.convertmessagebox',
],
],
- 'mediawiki.special.userrights.styles' => [
- 'styles' => 'resources/src/mediawiki.special/mediawiki.special.userrights.css',
- ],
'mediawiki.special.watchlist' => [
'scripts' => 'resources/src/mediawiki.special/mediawiki.special.watchlist.js',
'messages' => [
'oojs-ui.styles.icons-moderation',
],
'messages' => [
+ 'ooui-item-remove',
'ooui-outline-control-move-down',
'ooui-outline-control-move-up',
'ooui-outline-control-remove',
* Reset to default filters
*/
mw.rcfilters.Controller.prototype.resetToDefaults = function () {
- if ( this.applyParamChange( this._getDefaultParams() ) ) {
+ var params = this._getDefaultParams();
+ if ( this.applyParamChange( params ) ) {
// Only update the changes list if there was a change to actual filters
this.updateChangesList();
+ } else {
+ this.uriProcessor.updateURL( params );
}
};
if ( this.applyParamChange( {} ) ) {
// Only update the changes list if there was a change to actual filters
this.updateChangesList();
+ } else {
+ this.uriProcessor.updateURL();
}
if ( highlightedFilterNames ) {
if ( this.applyParamChange( params ) ) {
// Update changes list only if there was a difference in filter selection
this.updateChangesList();
+ } else {
+ this.uriProcessor.updateURL( params );
}
// Log filter grouping
* @return {mw.Uri} Updated Uri
*/
mw.rcfilters.UriProcessor.prototype.getUpdatedUri = function ( uriQuery ) {
- var uri = new mw.Uri(),
+ var titlePieces,
+ uri = new mw.Uri(),
unrecognizedParams = this.getUnrecognizedParams( uriQuery || uri.query );
if ( uriQuery ) {
uri.query = uriQuery;
}
+ // Normalize subpage to use &target= so we are always
+ // consistent in Special:RecentChangesLinked between the
+ // ?title=Special:RecentChangesLinked/TargetPage and
+ // ?title=Special:RecentChangesLinked&target=TargetPage
+ if ( uri.query.title && uri.query.title.indexOf( '/' ) !== -1 ) {
+ titlePieces = uri.query.title.split( '/' );
+
+ unrecognizedParams.title = titlePieces.shift();
+ unrecognizedParams.target = titlePieces.join( '/' );
+ }
+
uri.query = this.filtersModel.getMinimizedParamRepresentation(
$.extend(
true,
// Reapply unrecognized params and url version
uri.query = $.extend( true, {}, uri.query, unrecognizedParams, { urlversion: '2' } );
-
return uri;
};
} ) );
}
}
+ if ( 'maxbytes' in pi.parameters[ i ] ) {
+ descriptionContainer.append( $( '<div>', {
+ addClass: 'info',
+ append: Util.parseMsg( 'api-help-param-maxbytes', pi.parameters[ i ].maxbytes )
+ } ) );
+ }
+ if ( 'maxchars' in pi.parameters[ i ] ) {
+ descriptionContainer.append( $( '<div>', {
+ addClass: 'info',
+ append: Util.parseMsg( 'api-help-param-maxchars', pi.parameters[ i ].maxchars )
+ } ) );
+ }
helpField = new OO.ui.FieldLayout(
new OO.ui.Widget( {
$content: '\xa0',
.mw-userrights-groups * th {
text-align: left;
}
+
+/* Dynamically show/hide the expiry selection underneath each checkbox */
+input.mw-userrights-groupcheckbox:not( :checked ) ~ .mw-userrights-nested {
+ display: none;
+}
+
+/* Initial hide the expiry fields to prevent a FOUC on loading */
+/* The input fields gets unhidden by JavaScript when needed */
+.client-js .mw-userrights-expiryfield {
+ display: none;
+}
// Replace successbox with notifications
convertmessagebox();
- // Dynamically show/hide the expiry selection underneath each checkbox
- $( '#mw-userrights-form2 input[type=checkbox]' ).on( 'change', function ( e ) {
- $( '#mw-userrights-nested-' + e.target.id ).toggle( e.target.checked );
- } ).trigger( 'change' );
-
- // Also dynamically show/hide the "other time" input under each dropdown
+ // Dynamically show/hide the "other time" input under each dropdown
$( '.mw-userrights-nested select' ).on( 'change', function ( e ) {
$( e.target.parentNode ).find( 'input' ).toggle( $( e.target ).val() === 'other' );
- } ).trigger( 'change' );
+ } );
}( jQuery ) );
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="135" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"></a></div>lang=invalid:language:code</div></div></div>
!! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>lang=invalid.language.code</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>lang=invalid:language:code</figcaption></figure>
!! end
!! test
!! wikitext
<div title="[[Main Page]]"></div>
!! html
-<div title="[[Main Page]]"></div>
+<div title="[[Main Page]]"></div>
!! end
!! wikitext
<div title="[http://example.com/ link]"></div>
!! html
-<div title="[http://example.com/ link]"></div>
+<div title="[http://example.com/ link]"></div>
!! end
-{H|foAjrjvi=>sr-el:" onload="alert(1)" data-foo="}-
[[File:Foobar.jpg|alt=-{}-foAjrjvi-{}-]]
-!! html
+!! html/php
<p>
</p><p><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" onload="alert(1)" data-foo="" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
</p>
+!! html/parsoid
+<p><meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"foAjrjvi","l":"sr-el","t":"\" onload=\"alert(1)\" data-foo=\""}]}'/></p>
+
+<p><span class="mw-default-size" typeof="mw:Image"><a href="./Датотека:Foobar.jpg"><img alt="foAjrjvi" resource="./Датотека:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"foAjrjvi","resource":"./Датотека:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=-{}-foAjrjvi-{}-","resource":"File:Foobar.jpg"}}'/></a></span></p>
!! end
!! test
<p><a href="#Foo_bar">#Foo bar</a>
</p>
!! end
+
+!! test
+T51672: Test for brackets in attributes of elements in external link texts
+!! wikitext
+[http://example.com/ link <span title="title with [brackets]">span</span>]
+[http://example.com/ link <span title="title with [brackets]">span</span>]
+
+!! html/php
+<p><a rel="nofollow" class="external text" href="http://example.com/">link <span title="title with [brackets]">span</span></a>
+<a rel="nofollow" class="external text" href="http://example.com/">link <span title="title with [brackets]">span</span></a>
+</p>
+!! end
+
+!! test
+T72875: Test for brackets in attributes of elements in internal link texts
+!! wikitext
+[[Foo|link <span title="title with [[double brackets]]">span</span>]]
+[[Foo|link <span title="title with [[double brackets]]">span</span>]]
+
+!! html/php
+<p><a href="/wiki/Foo" title="Foo">link <span title="title with [[double brackets]]">span</span></a>
+<a href="/wiki/Foo" title="Foo">link <span title="title with [[double brackets]]">span</span></a>
+</p>
+!! end
+
+!! test
+T179544: {{anchorencode:}} output should be always usable in links
+!! config
+wgFragmentMode=[ 'html5' ]
+!! wikitext
+<span id="{{anchorencode:[foo]}}"></span>[[#{{anchorencode:[foo]}}]]
+!! html/php
+<p><span id="[foo]"></span><a href="#[foo]">#[foo]</a>
+</p>
+!! end
+
+## ------------------------------
+## Parsoid section-wrapping tests
+## ------------------------------
+!! test
+Section wrapping for well-nested sections (no leading content)
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+= 1 =
+a
+
+= 2 =
+b
+
+== 2.1 ==
+c
+
+== 2.2 ==
+d
+
+=== 2.2.1 ===
+e
+
+= 3 =
+f
+!! html/parsoid
+<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+</section><section data-mw-section-id="2"><h1 id="2"> 2 </h1>
+<p>b</p>
+
+<section data-mw-section-id="3"><h2 id="2.1"> 2.1 </h2>
+<p>c</p>
+
+</section><section data-mw-section-id="4"><h2 id="2.2"> 2.2 </h2>
+<p>d</p>
+
+<section data-mw-section-id="5"><h3 id="2.2.1"> 2.2.1 </h3>
+<p>e</p>
+
+</section></section></section><section data-mw-section-id="6"><h1 id="3"> 3 </h1>
+<p>f</p>
+
+</section>
+!! end
+
+!! test
+Section wrapping for well-nested sections (with leading content)
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+Para 1.
+
+Para 2 with a <div>nested in it</div>
+
+Para 3.
+
+= 1 =
+a
+
+= 2 =
+b
+
+== 2.1 ==
+c
+!! html/parsoid
+<section data-mw-section-id="0"><p>Para 1.</p>
+
+<p>Para 2 with a </p><div>nested in it</div>
+
+<p>Para 3.</p>
+
+</section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+</section><section data-mw-section-id="2"><h1 id="2"> 2 </h1>
+<p>b</p>
+
+<section data-mw-section-id="3"><h2 id="2.1"> 2.1 </h2>
+<p>c</p>
+
+</section></section>
+!! end
+
+!! test
+Section wrapping with template-generated sections (good nesting 1)
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+= 1 =
+a
+
+{{echo|1=
+== 1.1 ==
+b
+}}
+
+== 1.2 ==
+c
+
+= 2 =
+d
+!! html/parsoid
+<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,33,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.1 ==\nb"}},"i":0}}]}'> 1.1 </h2><span about="#mwt1">
+</span><p about="#mwt1">b</p>
+</section><section data-mw-section-id="3"><h2 id="1.2"> 1.2 </h2>
+<p>c</p>
+
+</section></section><section data-mw-section-id="4"><h1 id="2"> 2 </h1>
+<p>d</p></section>
+!! end
+
+# In this example, the template scope is mildly expanded to incorporate the
+# trailing newline after the transclusion since that is part of section 1.1.1
+!! test
+Section wrapping with template-generated sections (good nesting 2)
+!! options
+parsoid={
+ "wrapSections": true,
+ "modes": ["wt2html", "wt2wt"]
+}
+!! wikitext
+= 1 =
+a
+
+{{echo|1=
+== 1.1 ==
+b
+=== 1.1.1 ===
+d
+}}
+= 2 =
+e
+!! html/parsoid
+<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,50,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.1 ==\nb\n=== 1.1.1 ===\nd"}},"i":0}},"\n"]}'> 1.1 </h2><span about="#mwt1">
+</span><p about="#mwt1">b</p><span about="#mwt1">
+</span><section data-mw-section-id="-1" about="#mwt1"><h3 about="#mwt1" id="1.1.1"> 1.1.1 </h3><span about="#mwt1">
+</span><p about="#mwt1">d</p><span about="#mwt1">
+</span></section></section></section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="2"> 2 </h1>
+<p>e</p></section>
+!! end
+
+# In this example, the template scope is mildly expanded to incorporate the
+# trailing newline after the transclusion since that is part of section 1.2.1
+!! test
+Section wrapping with template-generated sections (good nesting 3)
+!! options
+parsoid={
+ "wrapSections": true,
+ "modes": ["wt2html", "wt2wt"]
+}
+!! wikitext
+= 1 =
+a
+
+{{echo|1=
+x
+== 1.1 ==
+b
+==1.2==
+c
+===1.2.1===
+d
+}}
+= 2 =
+e
+!! html/parsoid
+<section data-mw-section-id="1" data-parsoid="{}"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"dsr":[9,60,0,0],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"x\n== 1.1 ==\nb\n==1.2==\nc\n===1.2.1===\nd"}},"i":0}},"\n"]}'>x</p><span about="#mwt1">
+</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="1.1"> 1.1 </h2><span about="#mwt1">
+</span><p about="#mwt1">b</p><span about="#mwt1">
+</span></section><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="1.2">1.2</h2><span about="#mwt1">
+</span><p about="#mwt1">c</p><span about="#mwt1">
+</span><section data-mw-section-id="-1" about="#mwt1"><h3 about="#mwt1" id="1.2.1">1.2.1</h3><span about="#mwt1">
+</span><p about="#mwt1">d</p><span about="#mwt1">
+</span></section></section></section><section data-mw-section-id="5"><h1 id="2"> 2 </h1>
+<p>e</p></section>
+!! end
+
+# Because of section-wrapping and template-wrapping interactions,
+# the scope of the template is expanded so that the template markup
+# is valid in the presence of <section> tags.
+!! test
+Section wrapping with template-generated sections (bad nesting 1)
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+= 1 =
+a
+
+{{echo|1=
+= 2 =
+b
+== 2.1 ==
+c
+}}
+
+d
+
+= 3 =
+e
+!! html/parsoid
+<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+</section><section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="2" data-parsoid='{"dsr":[9,45,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"= 2 =\nb\n== 2.1 ==\nc"}},"i":0}},"\n\nd\n\n"]}'> 2 </h1><span about="#mwt1">
+</span><p about="#mwt1">b</p><span about="#mwt1">
+</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="2.1"> 2.1 </h2><span about="#mwt1">
+</span><p about="#mwt1">c</p><span about="#mwt1">
+
+</span><p about="#mwt1">d</p><span about="#mwt1">
+
+</span></section></section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
+<p>e</p></section>
+!! end
+
+# Because of section-wrapping and template-wrapping interactions,
+# additional template wrappers are added to <section> tags
+# so that template wrapping semantics are valid whether section
+# tags are retained or stripped. But, the template scope can expand
+# greatly when accounting for section tags.
+!! test
+Section wrapping with template-generated sections (bad nesting 2)
+!! options
+parsoid={
+ "wrapSections": true,
+ "modes": ["wt2html", "wt2wt"]
+}
+!! wikitext
+= 1 =
+a
+
+{{echo|1=
+== 1.2 ==
+b
+= 2 =
+c
+}}
+
+d
+
+= 3 =
+e
+!! html/parsoid
+<section data-mw-section-id="1" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["= 1 =\na\n\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.2 ==\nb\n= 2 =\nc"}},"i":0}},"\n\nd\n\n"]}'><h1 id="1"> 1 </h1>
+<p>a</p>
+
+<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.2 ==\nb\n= 2 =\nc"}},"i":0}}]}'> 1.2 </h2><span about="#mwt1">
+</span><p about="#mwt1">b</p><span about="#mwt1">
+</span></section></section><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="2"> 2 </h1><span about="#mwt1">
+</span><p about="#mwt1">c</p>
+
+<p>d</p>
+</section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="3"> 3 </h1>
+<p>e</p></section>
+!! end
+
+!! test
+Section wrapping with uneditable lead section + div wrapping multiple sections
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+foo
+
+<div style="border:1px solid red;">
+= 1 =
+a
+
+== 1.1 ==
+b
+
+= 2 =
+c
+</div>
+
+= 3 =
+d
+
+== 3.1 ==
+e
+!! html/parsoid
+<section data-mw-section-id="-1"><p>foo</p>
+
+</section><section data-mw-section-id="-2"><div style="border:1px solid red;">
+<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
+<p>a</p>
+
+<section data-mw-section-id="2"><h2 id="1.1"> 1.1 </h2>
+<p>b</p>
+
+</section></section><section data-mw-section-id="-1"><h1 id="2"> 2 </h1>
+<p>c</p>
+</section></div>
+
+</section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
+<p>d</p>
+
+<section data-mw-section-id="5"><h2 id="3.1"> 3.1 </h2>
+<p>e</p>
+</section></section>
+!! end
+
+!! test
+Section wrapping with editable lead section + div overlapping multiple sections
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+foo
+
+= 1 =
+a
+<div style="border:1px solid red;">
+b
+
+== 1.1 ==
+c
+
+= 2 =
+d
+</div>
+e
+
+= 3 =
+f
+
+== 3.1 ==
+g
+!! html/parsoid
+<section data-mw-section-id="0"><p>foo</p>
+
+</section><section data-mw-section-id="-1"><h1 id="1"> 1 </h1>
+<p>a</p>
+</section><section data-mw-section-id="-2"><div style="border:1px solid red;">
+<p>b</p>
+
+<section data-mw-section-id="2"><h2 id="1.1"> 1.1 </h2>
+<p>c</p>
+
+</section><section data-mw-section-id="-1"><h1 id="2"> 2 </h1>
+<p>d</p>
+</section></div>
+<p>e</p>
+
+</section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
+<p>f</p>
+
+<section data-mw-section-id="5"><h2 id="3.1"> 3.1 </h2>
+<p>g</p>
+</section></section>
+!! end
+
+!! test
+HTML header tags should not be wrapped in section tags
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+foo
+
+<h1>a</h1>
+
+= b =
+
+<h1>c</h1>
+
+= d =
+!! html/parsoid
+<section data-mw-section-id="0"><p>foo</p>
+
+<h1 id="a" data-parsoid='{"stx":"html"}'>a</h1>
+
+</section><section data-mw-section-id="1"><h1 id="b"> b </h1>
+
+<h1 id="c" data-parsoid='{"stx":"html"}'>c</h1>
+
+</section><section data-mw-section-id="2"><h1 id="d"> d </h1></section>
+!! end
* @since 1.18
*/
public function needsDB() {
- # if the test says it uses database tables, it needs the database
+ // If the test says it uses database tables, it needs the database
if ( $this->tablesUsed ) {
return true;
}
- # if the test says it belongs to the Database group, it needs the database
+ // If the test class says it belongs to the Database group, it needs the database.
+ // NOTE: This ONLY checks for the group in the class level doc comment.
$rc = new ReflectionClass( $this );
if ( preg_match( '/@group +Database/im', $rc->getDocComment() ) ) {
return true;
}
/**
- * @group Database
* @covers Parser::parse
*/
public function testTrackingCategory() {
}
/**
- * @group Database
* @covers Parser::parse
*/
public function testTrackingCategorySpecial() {
);
}
+ /**
+ * @covers Html::warningBox
+ * @covers Html::messageBox
+ */
+ public function testWarningBox() {
+ $this->assertEquals(
+ Html::warningBox( 'warn' ),
+ '<div class="warningbox">warn</div>'
+ );
+ }
+
+ /**
+ * @covers Html::errorBox
+ * @covers Html::messageBox
+ */
+ public function testErrorBox() {
+ $this->assertEquals(
+ Html::errorBox( 'err' ),
+ '<div class="errorbox">err</div>'
+ );
+ $this->assertEquals(
+ Html::errorBox( 'err', 'heading' ),
+ '<div class="errorbox"><h2>heading</h2>err</div>'
+ );
+ }
+
+ /**
+ * @covers Html::successBox
+ * @covers Html::messageBox
+ */
+ public function testSuccessBox() {
+ $this->assertEquals(
+ Html::successBox( 'great' ),
+ '<div class="successbox">great</div>'
+ );
+ $this->assertEquals(
+ Html::successBox( '<script>beware no escaping!</script>' ),
+ '<div class="successbox"><script>beware no escaping!</script></div>'
+ );
+ }
+
/**
* List of input element types values introduced by HTML5
* Full list at https://www.w3.org/TR/html-markup/input.html
use Wikimedia\TestingAccessWrapper;
+/**
+ * @group Database
+ */
class MessageTest extends MediaWikiLangTestCase {
protected function setUp() {
/**
* FIXME: This should not need database, but Language#formatExpiry does (T57912)
- * @group Database
* @covers Message::expiryParam
* @covers Message::expiryParams
*/
/**
* Auth-less test of Title::isValidMoveOperation
*
- * @group Database
* @param string $source
* @param string $target
* @param array|string|bool $expected Required error
/**
* @dataProvider dataIsCountable
- * @group Database
* @covers TextContent::isCountable
*/
public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
<?php
+use Wikimedia\TestingAccessWrapper;
+
/**
* @covers DifferenceEngine
*
$this->assertEquals( $revs[2], $diffEngine->getNewid(), 'diff get new id' );
}
+ public function provideLocaliseTitleTooltipsTestData() {
+ return [
+ 'moved paragraph left shoud get new location title' => [
+ '<a class="mw-diff-movedpara-left">⚫</a>',
+ '<a class="mw-diff-movedpara-left" title="(diff-paragraph-moved-tonew)">⚫</a>',
+ ],
+ 'moved paragraph right shoud get old location title' => [
+ '<a class="mw-diff-movedpara-right">⚫</a>',
+ '<a class="mw-diff-movedpara-right" title="(diff-paragraph-moved-toold)">⚫</a>',
+ ],
+ 'nothing changed when key not hit' => [
+ '<a class="mw-diff-movedpara-rightis">⚫</a>',
+ '<a class="mw-diff-movedpara-rightis">⚫</a>',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideLocaliseTitleTooltipsTestData
+ */
+ public function testAddLocalisedTitleTooltips( $input, $expected ) {
+ $this->setContentLang( 'qqx' );
+ $diffEngine = TestingAccessWrapper::newFromObject( new DifferenceEngine() );
+ $this->assertEquals( $expected, $diffEngine->addLocalisedTitleTooltips( $input ) );
+ }
+
}
<?php
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
class InstallDocFormatterTest extends MediaWikiTestCase {
/**
- * @covers InstallDocFormatter::format
+ * @covers InstallDocFormatter
* @dataProvider provideDocFormattingTests
*/
public function testFormat( $expected, $unformattedText, $message = '' ) {
];
}
+ public function testPreemtiveRefresh() {
+ $value = 'KatCafe';
+ $wasSet = 0;
+ $func = function ( $old, &$ttl, &$opts, $asOf ) use ( &$wasSet, $value )
+ {
+ ++$wasSet;
+ return $value;
+ };
+
+ $cache = new NearExpiringWANObjectCache( [
+ 'cache' => new HashBagOStuff(),
+ 'pool' => 'empty'
+ ] );
+
+ $wasSet = 0;
+ $key = wfRandomString();
+ $opts = [ 'lowTTL' => 30 ];
+ $v = $cache->getWithSetCallback( $key, 20, $func, $opts );
+ $this->assertEquals( $value, $v, "Value returned" );
+ $this->assertEquals( 1, $wasSet, "Value calculated" );
+ $v = $cache->getWithSetCallback( $key, 20, $func, $opts );
+ $this->assertEquals( 2, $wasSet, "Value re-calculated" );
+
+ $wasSet = 0;
+ $key = wfRandomString();
+ $opts = [ 'lowTTL' => 1 ];
+ $v = $cache->getWithSetCallback( $key, 30, $func, $opts );
+ $this->assertEquals( $value, $v, "Value returned" );
+ $this->assertEquals( 1, $wasSet, "Value calculated" );
+ $v = $cache->getWithSetCallback( $key, 30, $func, $opts );
+ $this->assertEquals( 1, $wasSet, "Value cached" );
+
+ $cache = new PopularityRefreshingWANObjectCache( [
+ 'cache' => new HashBagOStuff(),
+ 'pool' => 'empty'
+ ] );
+
+ $now = microtime( true ); // reference time
+ $wasSet = 0;
+ $key = wfRandomString();
+ $opts = [ 'hotTTR' => 900 ];
+ $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
+ $this->assertEquals( $value, $v, "Value returned" );
+ $this->assertEquals( 1, $wasSet, "Value calculated" );
+ $cache->setTime( $now + 30 );
+ $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
+ $this->assertEquals( 1, $wasSet, "Value cached" );
+
+ $wasSet = 0;
+ $key = wfRandomString();
+ $opts = [ 'hotTTR' => 10 ];
+ $cache->setTime( $now );
+ $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
+ $this->assertEquals( $value, $v, "Value returned" );
+ $this->assertEquals( 1, $wasSet, "Value calculated" );
+ $cache->setTime( $now + 30 );
+ $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
+ $this->assertEquals( 2, $wasSet, "Value re-calculated" );
+ }
+
/**
* @covers WANObjectCache::getWithSetCallback()
* @covers WANObjectCache::doGetWithSetCallback()
$this->assertEquals( $class, $wanCache->determineKeyClass( $key ) );
}
}
+
+class TimeAdjustableHashBagOStuff extends HashBagOStuff {
+ private $timeOverride = 0;
+
+ public function setTime( $time ) {
+ $this->timeOverride = $time;
+ }
+
+ protected function getCurrentTime() {
+ return $this->timeOverride ?: parent::getCurrentTime();
+ }
+}
+
+class TimeAdjustableWANObjectCache extends WANObjectCache {
+ private $timeOverride = 0;
+
+ public function setTime( $time ) {
+ $this->timeOverride = $time;
+ if ( $this->cache instanceof TimeAdjustableHashBagOStuff ) {
+ $this->cache->setTime( $time );
+ }
+ }
+
+ protected function getCurrentTime() {
+ return $this->timeOverride ?: parent::getCurrentTime();
+ }
+}
+
+class NearExpiringWANObjectCache extends TimeAdjustableWANObjectCache {
+ const CLOCK_SKEW = 1;
+
+ protected function worthRefreshExpiring( $curTTL, $lowTTL ) {
+ return ( ( $curTTL + self::CLOCK_SKEW ) < $lowTTL );
+ }
+}
+
+class PopularityRefreshingWANObjectCache extends TimeAdjustableWANObjectCache {
+ protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh, $now ) {
+ return ( ( $now - $asOf ) > $timeTillRefresh );
+ }
+}
);
$this->assertEquals(
- 'test:##dc89dcb43b28614da27660240af478b5',
+ 'test:BagOStuff-long-key:##dc89dcb43b28614da27660240af478b5',
$this->cache->makeKey( '𝕖𝕧𝕖𝕟', '𝕚𝕗', '𝕨𝕖', '𝕄𝔻𝟝', '𝕖𝕒𝕔𝕙',
'𝕒𝕣𝕘𝕦𝕞𝕖𝕟𝕥', '𝕥𝕙𝕚𝕤', '𝕜𝕖𝕪', '𝕨𝕠𝕦𝕝𝕕', '𝕤𝕥𝕚𝕝𝕝', '𝕓𝕖', '𝕥𝕠𝕠', '𝕝𝕠𝕟𝕘' )
);
+++ /dev/null
-<?php
-
-/**
- * @group ContentHandler
- * @group Database
- * ^--- important, causes temporary tables to be used instead of the real database
- */
-class WikiPageTestContentHandlerUseDB extends WikiPageTest {
-
- protected function setUp() {
- parent::setUp();
- $this->setMwGlobals( 'wgContentHandlerUseDB', false );
-
- $dbw = wfGetDB( DB_MASTER );
-
- $page_table = $dbw->tableName( 'page' );
- $revision_table = $dbw->tableName( 'revision' );
- $archive_table = $dbw->tableName( 'archive' );
-
- if ( $dbw->fieldExists( $page_table, 'page_content_model' ) ) {
- $dbw->query( "alter table $page_table drop column page_content_model" );
- $dbw->query( "alter table $revision_table drop column rev_content_model" );
- $dbw->query( "alter table $revision_table drop column rev_content_format" );
- $dbw->query( "alter table $archive_table drop column ar_content_model" );
- $dbw->query( "alter table $archive_table drop column ar_content_format" );
- }
- }
-
- /**
- * @covers WikiPage::getContentModel
- */
- public function testGetContentModel() {
- $page = $this->createPage(
- "WikiPageTest_testGetContentModel",
- "some text",
- CONTENT_MODEL_JAVASCRIPT
- );
-
- $page = new WikiPage( $page->getTitle() );
-
- // NOTE: since the content model is not recorded in the database,
- // we expect to get the default, namely CONTENT_MODEL_WIKITEXT
- $this->assertEquals( CONTENT_MODEL_WIKITEXT, $page->getContentModel() );
- }
-
- /**
- * @covers WikiPage::getContentHandler
- */
- public function testGetContentHandler() {
- $page = $this->createPage(
- "WikiPageTest_testGetContentHandler",
- "some text",
- CONTENT_MODEL_JAVASCRIPT
- );
-
- // NOTE: since the content model is not recorded in the database,
- // we expect to get the default, namely CONTENT_MODEL_WIKITEXT
- $page = new WikiPage( $page->getTitle() );
- $this->assertEquals( 'WikitextContentHandler', get_class( $page->getContentHandler() ) );
- }
-}
--- /dev/null
+<?php
+
+class LanguageCrhTest extends LanguageClassesTestCase {
+ /**
+ * @dataProvider provideAutoConvertToAllVariants
+ * @covers Language::autoConvertToAllVariants
+ */
+ public function testAutoConvertToAllVariants( $result, $value ) {
+ $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
+ }
+
+ public static function provideAutoConvertToAllVariants() {
+ return [
+ [ // general words, covering more of the alphabet
+ [
+ 'crh' => 'рузгярнынъ ruzgârnıñ Париж Parij',
+ 'crh-cyrl' => 'рузгярнынъ рузгярнынъ Париж Париж',
+ 'crh-latn' => 'ruzgârnıñ ruzgârnıñ Parij Parij',
+ ],
+ 'рузгярнынъ ruzgârnıñ Париж Parij'
+ ],
+ [ // general words, covering more of the alphabet
+ [
+ 'crh' => 'чёкюч çöküç элифбени elifbeni полициясы politsiyası',
+ 'crh-cyrl' => 'чёкюч чёкюч элифбени элифбени полициясы полициясы',
+ 'crh-latn' => 'çöküç çöküç elifbeni elifbeni politsiyası politsiyası',
+ ],
+ 'чёкюч çöküç элифбени elifbeni полициясы politsiyası'
+ ],
+ [ // general words, covering more of the alphabet
+ [
+ 'crh' => 'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv',
+ 'crh-cyrl' => 'хусусында хусусында акъшамларны акъшамларны опькеленюв опькеленюв',
+ 'crh-latn' => 'hususında hususında aqşamlarnı aqşamlarnı öpkelenüv öpkelenüv',
+ ],
+ 'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv'
+ ],
+ [ // general words, covering more of the alphabet
+ [
+ 'crh' => 'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız',
+ 'crh-cyrl' => 'кулюмсиреди кулюмсиреди айтмайджагъым айтмайджагъым козьяшсыз козьяшсыз',
+ 'crh-latn' => 'külümsiredi külümsiredi aytmaycağım aytmaycağım közyaşsız közyaşsız',
+ ],
+ 'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız'
+ ],
+ [ // exception words
+ [
+ 'crh' => 'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek',
+ 'crh-cyrl' => 'инструменталь инструменталь гургуль гургуль тюшюнмемек тюшюнмемек',
+ 'crh-latn' => 'instrumental instrumental gürgül gürgül tüşünmemek tüşünmemek',
+ ],
+ 'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek'
+ ],
+ [ // multi part words
+ [
+ 'crh' => 'эки юз eki yüz',
+ 'crh-cyrl' => 'эки юз эки юз',
+ 'crh-latn' => 'eki yüz eki yüz',
+ ],
+ 'эки юз eki yüz'
+ ],
+ [ // ALL CAPS, made up acronyms
+ [
+ 'crh' => 'ÑAB QIC ĞUK COT НЪАБ КЪЫДж ГЪУК ДЖОТ CA ДЖА',
+ 'crh-cyrl' => 'НЪАБ КЪЫДж ГЪУК ДЖОТ НЪАБ КЪЫДж ГЪУК ДЖОТ ДЖА ДЖА',
+ 'crh-latn' => 'ÑAB QIC ĞUK COT ÑAB QIC ĞUK COT CA CA',
+ ],
+ 'ÑAB QIC ĞUK COT НЪАБ КЪЫДж ГЪУК ДЖОТ CA ДЖА'
+ ],
+ ];
+ }
+}
foreach ( [ $paramsPlain, $paramsForHelp ] as $params ) {
foreach ( $params as $param => $config ) {
- if (
- isset( $config[ApiBase::PARAM_ISMULTI_LIMIT1] )
+ if ( isset( $config[ApiBase::PARAM_ISMULTI_LIMIT1] )
|| isset( $config[ApiBase::PARAM_ISMULTI_LIMIT2] )
) {
$this->assertTrue( !empty( $config[ApiBase::PARAM_ISMULTI] ), $param
$config[ApiBase::PARAM_ISMULTI_LIMIT2], $param
. 'PARAM_ISMULTI limit cannot be smaller for users with apihighlimits rights' );
}
+ if ( isset( $config[ApiBase::PARAM_MAX_BYTES] )
+ || isset( $config[ApiBase::PARAM_MAX_CHARS] )
+ ) {
+ $default = isset( $config[ApiBase::PARAM_DFLT] ) ? $config[ApiBase::PARAM_DFLT] : null;
+ $type = isset( $config[ApiBase::PARAM_TYPE] ) ? $config[ApiBase::PARAM_TYPE]
+ : gettype( $default );
+ $this->assertContains( $type, [ 'NULL', 'string', 'text', 'password' ],
+ 'PARAM_MAX_BYTES/CHARS is only supported for string-like types' );
+ }
}
}
}