* Ebrahim Byagowi
* Edward Z. Yang
* Elvis Stansvik
+* Eranroz
* Erwin Dokter
* Federico Leva
* FunPika
output.
* (bug 14202) $wgUseTeX has been superseded by the Math extension. To re-enable
math conversion after upgrading, obtain the Math extension from SVN or from
- http://www.mediawiki.org/wiki/Extension:Math and add to LocalSettings.php:
+ https://www.mediawiki.org/wiki/Extension:Math and add to LocalSettings.php:
require_once "$IP/extensions/Math/Math.php";
* $wgProfiler is now a configuration array, see StartProfiler.sample for
details.
whether a page is an article or not. $wgUseCommaCount is now deprecated.
* $wgEnableDublinCoreRdf and $wgEnableCreativeCommonsRdf no longer work in core,
and the functionality has been moved to the relevant extensions. See
- http://www.mediawiki.org/wiki/Extension:DublinCoreRdf and
- http://www.mediawiki.org/wiki/Extension:CreativeCommonsRdf as appropriate.
+ https://www.mediawiki.org/wiki/Extension:DublinCoreRdf and
+ https://www.mediawiki.org/wiki/Extension:CreativeCommonsRdf as appropriate.
* (bug 21107) Split error "customcssjsprotected" into separate messages for JS and CSS
* Removed $wgCheckCopyrightUpload from DefaultSettings, since the relevant feature
was removed in about 1.5.
will be made on the development trunk and appear in the next quarterly release.
Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
=== Configuration changes in 1.12 ===
* Marking edits as bot edits with Special:Contributions?bot=1 now requires the
The new preprocessor syntax has been documented in Backus-Naur Form at:
-http://www.mediawiki.org/wiki/Preprocessor_ABNF
+https://www.mediawiki.org/wiki/Preprocessor_ABNF
The ExpandTemplates extension now has the ability to generate an XML parse
tree from wikitext source. This parse tree corresponds closely to the grammar
=== API changes in 1.12 ===
-Full API documentation is available at http://www.mediawiki.org/wiki/API
+Full API documentation is available at https://www.mediawiki.org/wiki/API
* (bug 11275) Enable descending sort in categorymembers
* (bug 11308) Allow the API to output the image metadata
will be made on the development trunk and appear in the next quarterly release.
Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
== Configuration changes since 1.10 ==
== API changes since 1.10 ==
-Full API documentation is available at http://www.mediawiki.org/wiki/API
+Full API documentation is available at https://www.mediawiki.org/wiki/API
* New properties: links, templates, images, langlinks, categories, external
links
will be made on the development trunk and appear in the next quarterly release.
Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
== Configuration changes ==
groups. Note that this does *not* allow you to make pages which are only
accessible to certain groups.
- For details see: http://www.mediawiki.org/wiki/Manual:User_rights
+ For details see: https://www.mediawiki.org/wiki/Manual:User_rights
E-mail:
User-to-user e-mail can now be restricted to require a mail-back confirmation
* 'live preview' reduces preview reload burden on supported browsers
* support for external editors for files and wiki pages:
- http://www.mediawiki.org/wiki/Manual:External_editors
-* Schema reworking: http://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
+ https://www.mediawiki.org/wiki/Manual:External_editors
+* Schema reworking: https://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
* (bug 15) Allow editors to view diff of their change before actually submitting an edit
* (bug 190) Hide your own edits on the watchlist
* (bug 510): Special:Randompage now works for other namespaces than NS_MAIN.
If you have trouble, remember to read this whole file and the online FAQ page
before asking for help:
-http://www.mediawiki.org/wiki/Manual:FAQ
+https://www.mediawiki.org/wiki/Manual:FAQ
=== READ THIS FIRST: Upgrading ===
* More extension hooks have been added.
* Authentication plugin hook.
* More internal code documentation, generated with phpdoc:
- http://www.mediawiki.org/docs/html/
+ https://doc.wikimedia.org/mediawiki-core/master/php/html/
=== Optimization ===
built up on MediaWiki.org, and is covered under the GNU Free Documentation
License:
- http://www.mediawiki.org/
+ https://www.mediawiki.org/
=== Mailing list ===
not tested and unlikely to work.
Support for rendering mathematical formulas requires installing the Math extension,
-see http://www.mediawiki.org/wiki/Extension:Math
+see https://www.mediawiki.org/wiki/Extension:Math
Don't forget to check the RELEASE-NOTES file...
notes on particular operating systems and workarounds for difficult hosting
environments:
-http://www.mediawiki.org/wiki/Manual:Installation_guide
+https://www.mediawiki.org/wiki/Manual:Installation_guide
******************* WARNING *******************
| will appear. It is common in this case to use w as the folder name and |
| /wiki/ as the virtual article path where your articles pretend to be. |
| |
- | See: http://www.mediawiki.org/wiki/Manual:Short_URL |
+ | See: https://www.mediawiki.org/wiki/Manual:Short_URL |
+--------------------------------------------------------------------------+
Hop into your browser and surf into the wiki directory. It'll direct you into
revision comparison pages using syntax such as [[Special:Diff/12345]],
[[Special:Diff/12345/prev]] or [[Special:Diff/12345/98765]].
* New user accounts' personal and talk pages are now watched by them by default.
+* Added SkinTemplateGetLanguageLink hook to allow changing the html of language
+ links.
=== Bug fixes in 1.23 ===
* (bug 41759) The "updated since last visit" markers (on history pages, recent
* (bug 56199) Raw option of parser functions must now match complete word,
to take effect.
* (bug 60543) Special:PrefixIndex forgot stripprefix=1 for "Next page" link
+* (bug 29762) Undoing an already-undone edit will now display an appropriate
+ message instead of leading the user to make a null edit.
=== Web API changes in 1.23 ===
* (bug 54884) action=parse&prop=categories now indicates hidden and missing
list=usercontribs.
* list=watchlist now uses the querying user's rights rather than the wlowner's
rights when checking whether wlprop=patrol is allowed.
+* (bug 32151) ApiWatch now has pageset capabilities (titles/pageids/generators).
+ Title parameter is now deprecated.
+* (bug 23005) Added action=revisiondelete.
+* Added siprop=restrictions to API action=query&meta=siteinfo for querying
+ possible page restriction (protection) levels and types.
=== Languages updated in 1.23 ===
This file provides an overview of the MediaWiki upgrade process. For help with
specific problems, check
-* the documentation at http://www.mediawiki.org
+* the documentation at https://www.mediawiki.org
* the mediawiki-l mailing list archive at
http://lists.wikimedia.org/pipermail/mediawiki-l/
* the bug tracker at https://bugzilla.wikimedia.org
== Overview ==
Comprehensive documentation on upgrading to the latest version of the software
-is available at http://www.mediawiki.org/wiki/Manual:Upgrading.
+is available at https://www.mediawiki.org/wiki/Manual:Upgrading.
=== Consult the release notes ===
the upgrade scripts are somewhat robust, there is no guarantee that things will
not fail, leaving the database in an inconsistent state.
-http://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki provides an overview of
+https://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki provides an overview of
the backup process. You should also refer to the documentation for your
database management system for information on backing up a database, and to
your operating system documentation for information on making copies of files.
For information about the MediaWiki database layout, such as a
description of the tables and their contents, please see:
- http://www.mediawiki.org/wiki/Manual:Database_layout
+ https://www.mediawiki.org/wiki/Manual:Database_layout
https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=blob_plain;f=maintenance/tables.sql;hb=HEAD
This is a brief overview of the new design.
More thorough and up-to-date information is available on the documentation
-wiki at http://www.mediawiki.org/
+wiki at https://www.mediawiki.org/
Primary classes:
is the convention Wikipedia uses.) In theory, it should be possible to enable
the appropriate rewrite rules by default, if you can reconfigure the web
server, but you'd need to alter LocalSettings.php too. See
-<http://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
+<https://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
If you really must mess around with the directory structure, note that the
following files *must* all be web-accessible for MediaWiki to function
== Documentation ==
MediaWiki's official documentation is split between two places: the source
-code, and <http://www.mediawiki.org/>. The source code documentation is written
+code, and <https://www.mediawiki.org/>. The source code documentation is written
exclusively by developers, and so is likely to be reliable (at worst,
outdated). However, it can be pretty sparse. mediawiki.org documentation is
often much more thorough, but it's maintained by a wiki that's open to
not-for-profit charity that operates Wikipedia. Wikimedia employs the lead
developer and several other paid developers, but commit access is given out
liberally and there are multiple very active volunteer developers as well. A
-list of developers can be found at <http://www.mediawiki.org/wiki/Developers>.
+list of developers can be found at <https://www.mediawiki.org/wiki/Developers>.
MediaWiki's bug tracker is at <https://bugzilla.wikimedia.org>. However, most
developers follow the bug tracker little or not at all. The best place to
* Squid: Can provide a drastic speedup and a major cut in resource
consumption, but enabling it may interfere with other applications. It might
be suitable for a separate mediawiki-squid package. For setup details, see:
- <http://www.mediawiki.org/wiki/Manual:Squid_caching>
+ <https://www.mediawiki.org/wiki/Manual:Squid_caching>
* rsvg or other SVG rasterizer: ImageMagick can be used for SVG support, but
is not ideal. Wikipedia (as of the time of this writing) uses rsvg. To
enable, set "$wgSVGConverter = 'rsvg';" (or other as appropriate).
$key: the section name
&$legend: the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may be overridden
+'PreferencesFormPreSave': Override preferences being saved
+ $formData: array of user submitted data
+ $form: PreferencesForm object, also a ContextSource
+ $user: User object with preferences to be saved set
+ &$result: boolean indicating success
+
'PrefixSearchBackend': Override the title prefix search used for OpenSearch and
AJAX search suggestions. Put results into &$results outparam and return false.
$ns : array of int namespace keys to search in
$sktemplate: SkinTemplate object
$nav_urls: array of tabs
+'SkinTemplateGetLanguageLink': After building the data for a language link from
+which the actual html is constructed.
+&$languageLink: array containing data about the link. The following keys can be
+ modified: href, text, title, class, lang, hreflang. Each of them is a string.
+$languageLinkTitle: Title object belonging to the external language link
+$title: Title object of the page the link belongs to
+
To alter the structured navigation links in SkinTemplates, there are three
hooks called in different spots:
The Language object handles all readable text produced by the software.
-See http://www.mediawiki.org/wiki/Localisation#General_use_.28for_developers.29
+See https://www.mediawiki.org/wiki/Localisation#General_use_.28for_developers.29
an older version, you'll need to use an extension function.
Online documentation (contains more informations):
-Magic words: http://www.mediawiki.org/wiki/Manual:Magic_words
-Variables: http://www.mediawiki.org/wiki/Manual:Variable
-Parser functions: http://www.mediawiki.org/wiki/Manual:Parser_functions
\ No newline at end of file
+Magic words: https://www.mediawiki.org/wiki/Manual:Magic_words
+Variables: https://www.mediawiki.org/wiki/Manual:Variable
+Parser functions: https://www.mediawiki.org/wiki/Manual:Parser_functions
\ No newline at end of file
each table and field.
Historical information and some other notes are available at
-http://www.mediawiki.org/wiki/Manual:Database_layout
+https://www.mediawiki.org/wiki/Manual:Database_layout
index.php
Main access point. It handles the most of requests.
- See http://www.mediawiki.org/wiki/Manual:Index.php
+ See https://www.mediawiki.org/wiki/Manual:Index.php
api.php
Script to provide an API for bots to fetch content and informations about
- the site and also modify it. See http://www.mediawiki.org/wiki/API
+ the site and also modify it. See https://www.mediawiki.org/wiki/API
for more informations.
img_auth.php
Script that only serve images to logged in users. To configure the wiki
- to use that script, see http://www.mediawiki.org/wiki/Manual:Image_Authorisation.
+ to use that script, see https://www.mediawiki.org/wiki/Manual:Image_Authorisation.
load.php
Used by ResourceLoader to serve minified, concatenated and gzipped CSS and JS.
To enable the profileinfo.php itself, you'll need to set $wgDBadminuser
and $wgDBadminpassword in your LocalSettings.php, as well as $wgEnableProfileInfo
- See also http://www.mediawiki.org/wiki/How_to_debug#Profiling.
+ See also https://www.mediawiki.org/wiki/How_to_debug#Profiling.
thumb.php
Script used to resize images if it is configured to be done when the web
This feature has led to a wide variety of "user styles" becoming available:
-http://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
+https://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
If you want a different look for your wiki, that gallery is a good place to start.
create complex custom skins for their wikis. It should be preferred over
editing the core Monobook skin directly.
-See http://www.mediawiki.org/wiki/Manual:Skinning for more information.
+See https://www.mediawiki.org/wiki/Manual:Skinning for more information.
== Extension skins ==
}
if ( !$wgCachePages ) {
- wfDebug( "$fname: CACHE DISABLED\n", false );
+ wfDebug( "$fname: CACHE DISABLED\n", 'log' );
return false;
}
$modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
$modsinceTime = strtotime( $modsince );
$ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
- wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", false );
- wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", false );
+ wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", 'log' );
+ wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", 'log' );
if ( ( $ismodsince >= $timestamp ) && $wgUser->validateCache( $ismodsince ) && $ismodsince >= $wgCacheEpoch ) {
ini_set( 'zlib.output_compression', 0 );
$this->disable();
$this->mLastModified = $lastmod;
- wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", 'log' );
return true;
} else {
- wfDebug( "$fname: READY client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ wfDebug( "$fname: READY client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", 'log' );
$this->mLastModified = $lastmod;
}
} else {
- wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
+ wfDebug( "$fname: client did not send If-Modified-Since header\n", 'log' );
$this->mLastModified = $lastmod;
}
return false;
'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
'ApiQueryWatchlistRaw' => 'includes/api/ApiQueryWatchlistRaw.php',
'ApiResult' => 'includes/api/ApiResult.php',
+ 'ApiRevisionDelete' => 'includes/api/ApiRevisionDelete.php',
'ApiRollback' => 'includes/api/ApiRollback.php',
'ApiRsd' => 'includes/api/ApiRsd.php',
'ApiSetNotificationTimestamp' => 'includes/api/ApiSetNotificationTimestamp.php',
* Expensive Querypages are already updated.
*/
$wgSpecialPageCacheUpdates = array(
- 'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' )
+ 'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' ),
+ 'Activeusers' => array( 'SpecialActiveUsers', 'cacheUpdate' ),
);
/**
* @since 1.21
*/
protected function getContentObject( $def_content = null ) {
- global $wgOut, $wgRequest;
+ global $wgOut, $wgRequest, $wgUser, $wgContLang;
wfProfileIn( __METHOD__ );
# Warn the user that something went wrong
$undoMsg = 'failure';
} else {
- # Inform the user of our success and set an automatic edit summary
- $undoMsg = 'success';
-
- # If we just undid one rev, use an autosummary
- $firstrev = $oldrev->getNext();
- if ( $firstrev && $firstrev->getId() == $undo ) {
- $userText = $undorev->getUserText();
- if ( $userText === '' ) {
- $undoSummary = wfMessage(
- 'undo-summary-username-hidden',
- $undo
- )->inContentLanguage()->text();
- } else {
- $undoSummary = wfMessage(
- 'undo-summary',
- $undo,
- $userText
- )->inContentLanguage()->text();
+ $oldContent = $this->mArticle->getPage()->getContent( Revision::RAW );
+ $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+ $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
+
+ if ( $newContent->equals( $oldContent ) ) {
+ # Tell the user that the undo results in no change,
+ # i.e. the revisions were already undone.
+ $undoMsg = 'nochange';
+ $content = false;
+ } else {
+ # Inform the user of our success and set an automatic edit summary
+ $undoMsg = 'success';
+
+ # If we just undid one rev, use an autosummary
+ $firstrev = $oldrev->getNext();
+ if ( $firstrev && $firstrev->getId() == $undo ) {
+ $userText = $undorev->getUserText();
+ if ( $userText === '' ) {
+ $undoSummary = wfMessage(
+ 'undo-summary-username-hidden',
+ $undo
+ )->inContentLanguage()->text();
+ } else {
+ $undoSummary = wfMessage(
+ 'undo-summary',
+ $undo,
+ $userText
+ )->inContentLanguage()->text();
+ }
+ if ( $this->summary === '' ) {
+ $this->summary = $undoSummary;
+ } else {
+ $this->summary = $undoSummary . wfMessage( 'colon-separator' )
+ ->inContentLanguage()->text() . $this->summary;
+ }
+ $this->undidRev = $undo;
}
- if ( $this->summary === '' ) {
- $this->summary = $undoSummary;
- } else {
- $this->summary = $undoSummary . wfMessage( 'colon-separator' )
- ->inContentLanguage()->text() . $this->summary;
- }
- $this->undidRev = $undo;
+ $this->formtype = 'diff';
}
- $this->formtype = 'diff';
}
} else {
// Failed basic sanity checks.
$undoMsg = 'norev';
}
- // Messages: undo-success, undo-failure, undo-norev
+ // Messages: undo-success, undo-failure, undo-norev, undo-nochange
$class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
$this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
if ( !( $e instanceof MWException ) || $e->isLoggable() ) {
$log = self::getLogMessage( $e );
if ( $wgLogExceptionBacktrace ) {
- wfDebugLog( 'exception', $log . "\n" . $e->getTraceAsString() . "\n" );
+ wfDebugLog( 'exception', $log . "\n" . $e->getTraceAsString() );
} else {
wfDebugLog( 'exception', $log );
}
$json = self::jsonSerializeException( $e, false, FormatJson::ALL_OK );
if ( $json !== false ) {
- wfDebugLog( 'exception-json', $json, false );
+ wfDebugLog( 'exception-json', $json, 'private' );
}
}
* $wgDebugComments - if on, some debug items may appear in comments in the HTML output.
*
* @param $text String
- * @param bool $logonly set true to avoid appearing in HTML when $wgDebugComments is set
- */
-function wfDebug( $text, $logonly = false ) {
+ * @param string|bool $dest Destination of the message:
+ * - 'all': both to the log and HTML (debug toolbar or HTML comments)
+ * - 'log': only to the log and not in HTML
+ * For backward compatibility, it can also take a boolean:
+ * - true: same as 'all'
+ * - false: same as 'log'
+ */
+function wfDebug( $text, $dest = 'all' ) {
global $wgDebugLogFile, $wgProfileOnly, $wgDebugRawPage, $wgDebugLogPrefix;
if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
return;
}
+ // Turn $dest into a string if it's a boolean (for b/c)
+ if ( $dest === true ) {
+ $dest = 'all';
+ } elseif ( $dest === false ) {
+ $dest = 'log';
+ }
+
$timer = wfDebugTimer();
if ( $timer !== '' ) {
$text = preg_replace( '/[^\n]/', $timer . '\0', $text, 1 );
}
- if ( !$logonly ) {
+ if ( $dest === 'all' ) {
MWDebug::debugMsg( $text );
}
* @param $text String
* @param bool $public whether to log the event in the public log if no private
* log file is specified, (default true)
- */
-function wfDebugLog( $logGroup, $text, $public = true ) {
+ * @param string|bool $dest Destination of the message:
+ * - 'all': both to the log and HTML (debug toolbar or HTML comments)
+ * - 'log': only to the log and not in HTML
+ * - 'private': only to the specifc log if set in $wgDebugLogGroups and
+ * discarded otherwise
+ * For backward compatibility, it can also take a boolean:
+ * - true: same as 'all'
+ * - false: same as 'private'
+ */
+function wfDebugLog( $logGroup, $text, $dest = 'all' ) {
global $wgDebugLogGroups;
+
$text = trim( $text ) . "\n";
+ // Turn $dest into a string if it's a boolean (for b/c)
+ if ( $dest === true ) {
+ $dest = 'all';
+ } elseif ( $dest === false ) {
+ $dest = 'private';
+ }
+
if ( !isset( $wgDebugLogGroups[$logGroup] ) ) {
- if ( $public === true ) {
- wfDebug( "[$logGroup] $text", false );
+ if ( $dest !== 'private' ) {
+ wfDebug( "[$logGroup] $text", $dest );
}
return;
}
+ if ( $dest === 'all' ) {
+ MWDebug::debugMsg( "[$logGroup] $text" );
+ }
+
$logConfig = $wgDebugLogGroups[$logGroup];
if ( is_array( $logConfig ) ) {
if ( isset( $logConfig['sample'] ) && mt_rand( 1, $logConfig['sample'] ) !== 1 ) {
$pipes = null;
$proc = proc_open( $cmd, $desc, $pipes );
if ( !$proc ) {
- wfDebugLog( 'exec', "proc_open() failed: $cmd\n" );
+ wfDebugLog( 'exec', "proc_open() failed: $cmd" );
$retval = -1;
return '';
}
}
if ( $logMsg !== false ) {
- wfDebugLog( 'exec', "$logMsg: $cmd\n" );
+ wfDebugLog( 'exec', "$logMsg: $cmd" );
}
return $outBuffer;
return false;
}
if ( !$wgCachePages ) {
- wfDebug( __METHOD__ . ": CACHE DISABLED\n", false );
+ wfDebug( __METHOD__ . ": CACHE DISABLED\n", 'log' );
return false;
}
$clientHeader = $this->getRequest()->getHeader( 'If-Modified-Since' );
if ( $clientHeader === false ) {
- wfDebug( __METHOD__ . ": client did not send If-Modified-Since header\n", false );
+ wfDebug( __METHOD__ . ": client did not send If-Modified-Since header\n", 'log' );
return false;
}
}
wfDebug( __METHOD__ . ": client sent If-Modified-Since: " .
- wfTimestamp( TS_ISO_8601, $clientHeaderTime ) . "\n", false );
+ wfTimestamp( TS_ISO_8601, $clientHeaderTime ) . "\n", 'log' );
wfDebug( __METHOD__ . ": effective Last-Modified: " .
- wfTimestamp( TS_ISO_8601, $maxModified ) . "\n", false );
+ wfTimestamp( TS_ISO_8601, $maxModified ) . "\n", 'log' );
if ( $clientHeaderTime < $maxModified ) {
- wfDebug( __METHOD__ . ": STALE, $info\n", false );
+ wfDebug( __METHOD__ . ": STALE, $info\n", 'log' );
return false;
}
# Not modified
# Give a 304 response code and disable body output
- wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", false );
+ wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", 'log' );
ini_set( 'zlib.output_compression', 0 );
$this->getRequest()->response()->header( "HTTP/1.1 304 Not Modified" );
$this->sendCacheControl();
# We'll purge the proxy cache explicitly, but require end user agents
# to revalidate against the proxy on each visit.
# Surrogate-Control controls our Squid, Cache-Control downstream caches
- wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", false );
+ wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", 'log' );
# start with a shorter timeout for initial testing
# header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
$response->header( 'Surrogate-Control: max-age=' . $wgSquidMaxage . '+' . $this->mSquidMaxage . ', content="ESI/1.0"' );
# to revalidate against the proxy on each visit.
# IMPORTANT! The Squid needs to replace the Cache-Control header with
# Cache-Control: s-maxage=0, must-revalidate, max-age=0
- wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", false );
+ wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", 'log' );
# start with a shorter timeout for initial testing
# header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
$response->header( 'Cache-Control: s-maxage=' . $this->mSquidMaxage . ', must-revalidate, max-age=0' );
} else {
# We do want clients to cache if they can, but they *must* check for updates
# on revisiting the page.
- wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **\n", false );
+ wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **\n", 'log' );
$response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
$response->header( "Cache-Control: private, must-revalidate, max-age=0" );
}
$response->header( "Last-Modified: {$this->mLastModified}" );
}
} else {
- wfDebug( __METHOD__ . ": no caching **\n", false );
+ wfDebug( __METHOD__ . ": no caching **\n", 'log' );
# In general, the absence of a last modified header should be enough to prevent
# the client from using its cache. We send a few other things just to make sure.
'emailaddress',
);
+ /**
+ * @return array
+ */
+ static function getSaveBlacklist() {
+ return self::$saveBlacklist;
+ }
+
/**
* @throws MWException
* @param $user User
$user->setOption( $key, $value );
}
+ wfRunHooks( 'PreferencesFormPreSave', array( $formData, $form, $user, &$result ) );
$user->saveSettings();
}
if ( $this->shownavigation ) {
$out->addHTML( $this->getPageHeader() );
if ( $this->numRows > 0 ) {
- $out->addHTML( $this->msg( 'showingresults' )->numParams(
+ $out->addHTML( $this->msg( 'showingresultsinrange' )->numParams(
min( $this->numRows, $this->limit ), # do not show the one extra row, if exist
- $this->offset + 1 )->parseAsBlock() );
+ $this->offset + 1, (min( $this->numRows, $this->limit ) + $this->offset) )->parseAsBlock() );
# Disable the "next" link when we reach the end
$paging = $this->getLanguage()->viewPrevNext( $this->getPageTitle( $par ), $this->offset,
$this->limit, $this->linkParameters(), ( $this->numRows <= $this->limit ) );
wfProfileOut( $fname . '-exception' );
wfProfileIn( $fname . '-includes' );
-require_once "$IP/includes/GlobalFunctions.php";
require_once "$IP/includes/normal/UtfNormalUtil.php";
+require_once "$IP/includes/GlobalFunctions.php";
require_once "$IP/includes/normal/UtfNormalDefines.php";
wfProfileOut( $fname . '-includes' );
);
}
-$wgDeferredUpdateList = array(); // b/c
-
wfProfileOut( $fname . '-defaults2' );
wfProfileIn( $fname . '-misc1' );
}
wfProfileOut( $fname . '-misc1' );
-if ( !defined( 'MW_SETUP_NO_CACHE' ) ) {
- wfProfileIn( $fname . '-memcached' );
+wfProfileIn( $fname . '-memcached' );
- $wgMemc = wfGetMainCache();
- $messageMemc = wfGetMessageCacheStorage();
- $parserMemc = wfGetParserCacheStorage();
- $wgLangConvMemc = wfGetLangConverterCacheStorage();
+$wgMemc = wfGetMainCache();
+$messageMemc = wfGetMessageCacheStorage();
+$parserMemc = wfGetParserCacheStorage();
+$wgLangConvMemc = wfGetLangConverterCacheStorage();
- wfDebug( 'CACHES: ' . get_class( $wgMemc ) . '[main] ' .
- get_class( $messageMemc ) . '[message] ' .
- get_class( $parserMemc ) . "[parser]\n" );
+wfDebug( 'CACHES: ' . get_class( $wgMemc ) . '[main] ' .
+ get_class( $messageMemc ) . '[message] ' .
+ get_class( $parserMemc ) . "[parser]\n" );
- wfProfileOut( $fname . '-memcached' );
- # # Most of the config is out, some might want to run hooks here.
- wfRunHooks( 'SetupAfterCache' );
-}
+wfProfileOut( $fname . '-memcached' );
+
+# # Most of the config is out, some might want to run hooks here.
+wfRunHooks( 'SetupAfterCache' );
wfProfileIn( $fname . '-session' );
}
wfProfileOut( $fname . '-session' );
+wfProfileIn( $fname . '-globals' );
-if ( !defined( 'MW_SETUP_NO_CONTEXT' ) ) {
- wfProfileIn( $fname . '-globals' );
-
- $wgContLang = Language::factory( $wgLanguageCode );
- $wgContLang->initEncoding();
- $wgContLang->initContLang();
+$wgContLang = Language::factory( $wgLanguageCode );
+$wgContLang->initEncoding();
+$wgContLang->initContLang();
- // Now that variant lists may be available...
- $wgRequest->interpolateTitle();
- $wgUser = RequestContext::getMain()->getUser(); # BackCompat
+// Now that variant lists may be available...
+$wgRequest->interpolateTitle();
+$wgUser = RequestContext::getMain()->getUser(); # BackCompat
- /**
- * @var $wgLang Language
- */
- $wgLang = new StubUserLang;
+/**
+ * @var $wgLang Language
+ */
+$wgLang = new StubUserLang;
- /**
- * @var OutputPage
- */
- $wgOut = RequestContext::getMain()->getOutput(); # BackCompat
+/**
+ * @var OutputPage
+ */
+$wgOut = RequestContext::getMain()->getOutput(); # BackCompat
- /**
- * @var $wgParser Parser
- */
- $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
+/**
+ * @var $wgParser Parser
+ */
+$wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
- if ( !is_object( $wgAuth ) ) {
- $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
- wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
- }
+if ( !is_object( $wgAuth ) ) {
+ $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
+ wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
+}
- # Placeholders in case of DB error
- $wgTitle = null;
+# Placeholders in case of DB error
+$wgTitle = null;
- wfProfileOut( $fname . '-globals' );
-}
+$wgDeferredUpdateList = array();
+wfProfileOut( $fname . '-globals' );
wfProfileIn( $fname . '-extensions' );
# Extension setup functions for extensions other than skins
}
$ilInterwikiCodeBCP47 = wfBCP47( $ilInterwikiCode );
- $languageLinks[] = array(
+ $languageLink = array(
'href' => $languageLinkTitle->getFullURL(),
'text' => $ilLangName,
'title' => $ilTitle,
'lang' => $ilInterwikiCodeBCP47,
'hreflang' => $ilInterwikiCodeBCP47,
);
+ wfRunHooks( 'SkinTemplateGetLanguageLink', array( &$languageLink, $languageLinkTitle, $this->getTitle() ) );
+ $languageLinks[] = $languageLink;
}
}
* @param $msg string
*/
protected function log( $msg ) {
- wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg\n" );
+ wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg" );
}
}
$ipList = gethostbynamel( $host );
if ( $ipList ) {
- wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
+ wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $base!" );
$found = true;
break;
} else {
- wfDebugLog( 'dnsblacklist', "Requested $host, not found in $base.\n" );
+ wfDebugLog( 'dnsblacklist', "Requested $host, not found in $base." );
}
}
}
* - 'registered-checkmatrix' - as above, using the 'checkmatrix' type.
* - 'userjs' - preferences with names starting with 'userjs-', intended to
* be used by user scripts.
+ * - 'special' - "preferences" that are not accessible via User::getOptions
+ * or User::setOptions.
* - 'unused' - preferences about which MediaWiki doesn't know anything.
* These are usually legacy options, removed in newer versions.
*
'registered-multiselect',
'registered-checkmatrix',
'userjs',
+ 'special',
'unused'
);
}
$prefs = Preferences::getPreferences( $this, $context );
$mapping = array();
+ // Pull out the "special" options, so they don't get converted as
+ // multiselect or checkmatrix.
+ $specialOptions = array_fill_keys( Preferences::getSaveBlacklist(), true );
+ foreach ( $specialOptions as $name => $value ) {
+ unset( $prefs[$name] );
+ }
+
// Multiselect and checkmatrix options are stored in the database with
// one key per option, each having a boolean value. Extract those keys.
$multiselectOptions = array();
$mapping[$key] = 'registered-multiselect';
} elseif ( isset( $checkmatrixOptions[$key] ) ) {
$mapping[$key] = 'registered-checkmatrix';
+ } elseif ( isset( $specialOptions[$key] ) ) {
+ $mapping[$key] = 'special';
} elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
$mapping[$key] = 'userjs';
} else {
$this->parserOutput = ParserCache::singleton()->getDirty( $this->page, $this->parserOptions );
if ( $this->parserOutput === false ) {
- wfDebugLog( 'dirty', "dirty missing\n" );
+ wfDebugLog( 'dirty', 'dirty missing' );
wfDebug( __METHOD__ . ": no dirty cache\n" );
return false;
} else {
wfDebug( __METHOD__ . ": sending dirty output\n" );
- wfDebugLog( 'dirty', "dirty output {$this->cacheKey}\n" );
+ wfDebugLog( 'dirty', "dirty output {$this->cacheKey}" );
$this->isDirty = true;
return true;
}
} elseif ( !$content instanceof TextContent ) {
// non-text content
wfHttpError( 415, "Unsupported Media Type", "The requested page uses the content model `"
- . $content->getModel() . "` which is not supported via this interface." );
+ . $content->getModel() . "` which is not supported via this interface." );
die();
} else {
// want a section?
}
/**
- * Throw a UsageException based on the errors in the Status object.
+ * Get error (as code, string) from a Status object.
*
- * @since 1.22
+ * @since 1.23
* @param Status $status Status object
- * @throws MWException
+ * @return array of code and error string
*/
- public function dieStatus( $status ) {
+ public function getErrorFromStatus( $status ) {
if ( $status->isGood() ) {
throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
}
// Translate message to code, for backwards compatability
$code = ApiBase::$messageMap[$code]['code'];
}
- $this->dieUsage( $msg->inLanguage( 'en' )->useDatabase( false )->plain(), $code );
+
+ return array( $code, $msg->inLanguage( 'en' )->useDatabase( false )->plain() );
+ }
+
+ /**
+ * Throw a UsageException based on the errors in the Status object.
+ *
+ * @since 1.22
+ * @param Status $status Status object
+ * @throws MWException
+ */
+ public function dieStatus( $status ) {
+
+ list( $code, $msg ) = $this->getErrorFromStatus( $status );
+ $this->dieUsage( $msg, $code );
}
// @codingStandardsIgnoreStart Allow long lines. Cannot split these.
* @ingroup API
*/
class ApiMain extends ApiBase {
-
/**
* When no format parameter is given, this format will be used
*/
'userrights' => 'ApiUserrights',
'options' => 'ApiOptions',
'imagerotate' => 'ApiImageRotate',
+ 'revisiondelete' => 'ApiRevisionDelete',
);
/**
}
}
$s .= "\n";
- wfDebugLog( 'api', $s, false );
+ wfDebugLog( 'api', $s, 'private' );
}
/**
array( 'code' => 'maxlag', 'info' => 'Waiting for host: x seconds lagged' ),
array( 'code' => 'maxlag', 'info' => 'Waiting for a database server: x seconds lagged' ),
array( 'code' => 'assertuserfailed', 'info' => 'Assertion that the user is logged in failed' ),
- array( 'code' => 'assertbotfailed', 'info' => 'Assertion that the user has the bot right failed' ),
+ array(
+ 'code' => 'assertbotfailed',
+ 'info' => 'Assertion that the user has the bot right failed'
+ ),
) );
}
$validation = true;
}
break;
+ case 'special':
+ $validation = "cannot be set by this module";
+ break;
case 'unused':
default:
$validation = "not a valid preference";
* @since 1.21 derives from ApiBase instead of ApiQueryBase
*/
class ApiPageSet extends ApiBase {
-
/**
* Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter
* @since 1.21
*/
private $mDefaultNamespace = NS_MAIN;
+ /**
+ * Add all items from $values into the result
+ * @param array $result output
+ * @param array $values values to add
+ * @param string $flag the name of the boolean flag to mark this element
+ * @param string $name if given, name of the value
+ */
+ private static function addValues( array &$result, $values, $flag = null, $name = null ) {
+ foreach ( $values as $val ) {
+ if ( $val instanceof Title ) {
+ $v = array();
+ ApiQueryBase::addTitleInfo( $v, $val );
+ } elseif ( $name !== null ) {
+ $v = array( $name => $val );
+ } else {
+ $v = $val;
+ }
+ if ( $flag !== null ) {
+ $v[$flag] = '';
+ }
+ $result[] = $v;
+ }
+ }
+
/**
* Constructor
* @param $dbSource ApiBase Module implementing getDB().
return $values;
}
+ /**
+ * Get an array of invalid/special/missing titles.
+ *
+ * @param $invalidChecks List of types of invalid titles to include.
+ * Recognized values are:
+ * - invalidTitles: Titles from $this->getInvalidTitles()
+ * - special: Titles from $this->getSpecialTitles()
+ * - missingIds: ids from $this->getMissingPageIDs()
+ * - missingRevIds: ids from $this->getMissingRevisionIDs()
+ * - missingTitles: Titles from $this->getMissingTitles()
+ * - interwikiTitles: Titles from $this->getInterwikiTitlesAsResult()
+ * @return array Array suitable for inclusion in the response
+ * @since 1.23
+ */
+ public function getInvalidTitlesAndRevisions( $invalidChecks = array( 'invalidTitles',
+ 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' )
+ ) {
+ $result = array();
+ if ( in_array( "invalidTitles", $invalidChecks ) ) {
+ self::addValues( $result, $this->getInvalidTitles(), 'invalid', 'title' );
+ }
+ if ( in_array( "special", $invalidChecks ) ) {
+ self::addValues( $result, $this->getSpecialTitles(), 'special', 'title' );
+ }
+ if ( in_array( "missingIds", $invalidChecks ) ) {
+ self::addValues( $result, $this->getMissingPageIDs(), 'missing', 'pageid' );
+ }
+ if ( in_array( "missingRevIds", $invalidChecks ) ) {
+ self::addValues( $result, $this->getMissingRevisionIDs(), 'missing', 'revid' );
+ }
+ if ( in_array( "missingTitles", $invalidChecks ) ) {
+ self::addValues( $result, $this->getMissingTitles(), 'missing' );
+ }
+ if ( in_array( "interwikiTitles", $invalidChecks ) ) {
+ self::addValues( $result, $this->getInterwikiTitlesAsResult() );
+ }
+
+ return $result;
+ }
+
/**
* Get the list of revision IDs (requested with the revids= parameter)
* @return array revID (int) => pageID (int)
}
$expiryarray[$p[0]] = $exp;
}
- $resultProtections[] = array( $p[0] => $protections[$p[0]],
- 'expiry' => ( $expiryarray[$p[0]] == $db->getInfinity() ?
- 'infinite' :
- wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] ) ) );
+ $resultProtections[] = array(
+ $p[0] => $protections[$p[0]],
+ 'expiry' => ( $expiryarray[$p[0]] == $db->getInfinity()
+ ? 'infinite'
+ : wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] )
+ )
+ );
}
$cascade = $params['cascade'];
class ApiPurge extends ApiBase {
private $mPageSet;
- /**
- * Add all items from $values into the result
- * @param array $result output
- * @param array $values values to add
- * @param string $flag the name of the boolean flag to mark this element
- * @param string $name if given, name of the value
- */
- private static function addValues( array &$result, $values, $flag = null, $name = null ) {
- foreach ( $values as $val ) {
- if ( $val instanceof Title ) {
- $v = array();
- ApiQueryBase::addTitleInfo( $v, $val );
- } elseif ( $name !== null ) {
- $v = array( $name => $val );
- } else {
- $v = $val;
- }
- if ( $flag !== null ) {
- $v[$flag] = '';
- }
- $result[] = $v;
- }
- }
-
/**
* Purges the cache of a page
*/
$pageSet = $this->getPageSet();
$pageSet->execute();
- $result = array();
- self::addValues( $result, $pageSet->getInvalidTitles(), 'invalid', 'title' );
- self::addValues( $result, $pageSet->getSpecialTitles(), 'special', 'title' );
- self::addValues( $result, $pageSet->getMissingPageIDs(), 'missing', 'pageid' );
- self::addValues( $result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid' );
- self::addValues( $result, $pageSet->getMissingTitles(), 'missing' );
- self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
+ $result = $pageSet->getInvalidTitlesAndRevisions();
foreach ( $pageSet->getGoodTitles() as $title ) {
$r = array();
}
$dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
- $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_CATEGORY ) );
- $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_CATEGORY ) );
+ $from = ( $params['from'] === null
+ ? null
+ : $this->titlePartToKey( $params['from'], NS_CATEGORY ) );
+ $to = ( $params['to'] === null
+ ? null
+ : $this->titlePartToKey( $params['to'], NS_CATEGORY ) );
$this->addWhereRange( 'cat_title', $dir, $from, $to );
$min = $params['min'];
// 'continue' always overrides 'from'
$from = ( $continue || $params['from'] === null ? null :
- $this->titlePartToKey( $params['from'], $params['namespace'] ) );
+ $this->titlePartToKey( $params['from'], $namespace ) );
$to = ( $params['to'] === null ? null :
- $this->titlePartToKey( $params['to'], $params['namespace'] ) );
+ $this->titlePartToKey( $params['to'], $namespace ) );
$this->addWhereRange( $pfx . $fieldTitle, 'newer', $from, $to );
-
if ( isset( $params['prefix'] ) ) {
$this->addWhere( $pfx . $fieldTitle . $db->buildLike( $this->titlePartToKey(
- $params['prefix'], $params['namespace'] ), $db->anyString() ) );
+ $params['prefix'], $namespace ), $db->anyString() ) );
}
$this->addFields( array( 'pl_title' => $pfx . $fieldTitle ) );
$this->addWhereFld( 'page_namespace', $params['namespace'] );
$dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
- $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], $params['namespace'] ) );
- $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], $params['namespace'] ) );
+ $from = ( $params['from'] === null
+ ? null
+ : $this->titlePartToKey( $params['from'], $params['namespace'] ) );
+ $to = ( $params['to'] === null
+ ? null
+ : $this->titlePartToKey( $params['to'], $params['namespace'] ) );
$this->addWhereRange( 'page_title', $dir, $from, $to );
if ( isset( $params['prefix'] ) ) {
// prefix.
$this->dieUsageMsg( array( 'invalidtitle', $titlePart ) );
}
+
return substr( $t->getDbKey(), 0, -1 );
}
$this->setContinueEnumParameter( 'continue',
$params['continue'] !== null ? $params['continue'] : '0|0'
);
+
return;
}
}
// of anoncontributors
$this->setContinueEnumParameter( 'continue', $continuePages );
}
+
return;
}
} elseif ( $params['excluderights'] ) {
// We've reached the one extra which shows that
// there are additional pages to be had. Stop here...
$this->setContinueEnumParameter( 'continue', $row->page . '|' . $row->user );
+
return;
}
);
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $row->page . '|' . $row->user );
+
return;
}
}
);
}
-
public function getDescription() {
return 'Get the list of logged-in contributors and ' .
'the count of anonymous contributors to a page';
} elseif ( $mode == 'all' ) {
$this->addWhereFld( 'ar_namespace', $params['namespace'] );
- $from = $params['from'] === null ? null : $this->titlePartToKey( $params['from'], $params['namespace'] );
- $to = $params['to'] === null ? null : $this->titlePartToKey( $params['to'], $params['namespace'] );
+ $from = $params['from'] === null
+ ? null
+ : $this->titlePartToKey( $params['from'], $params['namespace'] );
+ $to = $params['to'] === null
+ ? null
+ : $this->titlePartToKey( $params['to'], $params['namespace'] );
$this->addWhereRange( 'ar_title', $dir, $from, $to );
if ( isset( $params['prefix'] ) ) {
protected function getInitialisedRepoGroup() {
$repoGroup = RepoGroup::singleton();
$repoGroup->initialiseRepos();
+
return $repoGroup;
}
' (requires url and param ' . $modulePrefix . 'urlwidth)',
'mediatype' => ' mediatype - Adds the media type of the image',
'metadata' => ' metadata - Lists Exif metadata for the version of the image',
- 'commonmetadata' => ' commonmetadata - Lists file format generic metadata for the version of the image',
+ 'commonmetadata' => ' commonmetadata - Lists file format generic metadata ' .
+ 'for the version of the image',
'extmetadata' => ' extmetadata - Lists formatted metadata combined ' .
'from multiple sources. Results are HTML formatted.',
'archivename' => ' archivename - Adds the file name of the archive ' .
case 'rightsinfo':
$fit = $this->appendRightsInfo( $p );
break;
+ case 'restrictions':
+ $fit = $this->appendRestrictions( $p );
+ break;
case 'languages':
$fit = $this->appendLanguages( $p );
break;
$vcsVersion = $gitInfo->getHeadSHA1();
if ( $vcsVersion !== false ) {
$ret['vcs-system'] = 'git';
- $ret['vcs-version'] = $vcsVersion;
+ $ret['vcs-version'] = $vcsVersion;
$ret['vcs-url'] = $gitInfo->getHeadViewUrl();
$ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $gitInfo->getHeadCommitDate() );
} else {
$ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
}
}
+
if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
$ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
- $ret['license'] = SpecialPage::getTitleFor( 'Version', "License/{$ext['name']}" )->getLinkURL();
+ $ret['license'] = SpecialPage::getTitleFor(
+ 'Version',
+ "License/{$ext['name']}"
+ )->getLinkURL();
}
+
if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
- $ret['credits'] = SpecialPage::getTitleFor( 'Version', "Credits/{$ext['name']}" )->getLinkURL();
+ $ret['credits'] = SpecialPage::getTitleFor(
+ 'Version',
+ "Credits/{$ext['name']}"
+ )->getLinkURL();
}
}
$data[] = $ret;
return $this->getResult()->addValue( 'query', $property, $data );
}
+ protected function appendRestrictions( $property ) {
+ global $wgRestrictionTypes, $wgRestrictionLevels,
+ $wgCascadingRestrictionLevels, $wgSemiprotectedRestrictionLevels;
+
+ $data = array(
+ 'types' => $wgRestrictionTypes,
+ 'levels' => $wgRestrictionLevels,
+ 'cascadinglevels' => $wgCascadingRestrictionLevels,
+ 'semiprotectedlevels' => $wgSemiprotectedRestrictionLevels,
+ );
+
+ $this->getResult()->setIndexedTagName( $data['types'], 'type' );
+ $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
+ $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
+ $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
+
+ return $this->getResult()->addValue( 'query', $property, $data );
+ }
+
public function appendLanguages( $property ) {
$params = $this->extractRequestParams();
$langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
'extensions',
'fileextensions',
'rightsinfo',
+ 'restrictions',
'languages',
'skins',
'extensiontags',
' extensions - Returns extensions installed on the wiki',
' fileextensions - Returns list of file extensions allowed to be uploaded',
' rightsinfo - Returns wiki rights (license) information if available',
+ ' restrictions - Returns information on available restriction (protection) types',
' languages - Returns a list of languages MediaWiki supports' .
"(optionally localised by using {$p}inlanguagecode)",
' skins - Returns a list of all enabled skins',
$vals['commenthidden'] = '';
$anyHidden = true;
}
- if ( Revision::userCanBitfield( $row->rev_deleted, Revision::DELETED_COMMENT, $this->getUser() ) ) {
+
+ $userCanView = Revision::userCanBitfield(
+ $row->rev_deleted,
+ Revision::DELETED_COMMENT, $this->getUser()
+ );
+
+ if ( $userCanView ) {
if ( $this->fld_comment ) {
$vals['comment'] = $row->rev_comment;
}
--- /dev/null
+<?php
+/**
+ * Created on Jun 25, 2013
+ *
+ * Copyright © 2013 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * 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
+ * @since 1.23
+ */
+
+/**
+ * API interface to RevDel. The API equivalent of Special:RevisionDelete.
+ * Requires API write mode to be enabled.
+ *
+ * @ingroup API
+ */
+class ApiRevisionDelete extends ApiBase {
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+ $user = $this->getUser();
+
+ if ( !$user->isAllowed( RevisionDeleter::getRestriction( $params['type'] ) ) ) {
+ $this->dieUsageMsg( 'badaccess-group0' );
+ }
+
+ if ( !$params['ids'] ) {
+ $this->dieUsage( "At least one value is required for 'ids'", 'badparams' );
+ }
+
+ $hide = $params['hide'] ?: array();
+ $show = $params['show'] ?: array();
+ if ( array_intersect( $hide, $show ) ) {
+ $this->dieUsage( "Mutually exclusive values for 'hide' and 'show'", 'badparams' );
+ } elseif ( !$hide && !$show ) {
+ $this->dieUsage( "At least one value is required for 'hide' or 'show'", 'badparams' );
+ }
+ $bits = array(
+ 'content' => RevisionDeleter::getRevdelConstant( $params['type'] ),
+ 'comment' => Revision::DELETED_COMMENT,
+ 'user' => Revision::DELETED_USER,
+ );
+ $bitfield = array();
+ foreach ( $bits as $key => $bit ) {
+ if ( in_array( $key, $hide ) ) {
+ $bitfield[$bit] = 1;
+ } elseif ( in_array( $key, $show ) ) {
+ $bitfield[$bit] = 0;
+ } else {
+ $bitfield[$bit] = -1;
+ }
+ }
+
+ if ( $params['suppress'] === 'yes' ) {
+ if ( !$user->isAllowed( 'suppressrevision' ) ) {
+ $this->dieUsageMsg( 'badaccess-group0' );
+ }
+ $bitfield[Revision::DELETED_RESTRICTED] = 1;
+ } elseif ( $params['suppress'] === 'no' ) {
+ $bitfield[Revision::DELETED_RESTRICTED] = 0;
+ } else {
+ $bitfield[Revision::DELETED_RESTRICTED] = -1;
+ }
+
+ $targetObj = null;
+ if ( $params['target'] ) {
+ $targetObj = Title::newFromText( $params['target'] );
+ }
+ $targetObj = RevisionDeleter::suggestTarget( $params['type'], $targetObj, $params['ids'] );
+ if ( $targetObj === null ) {
+ $this->dieUsage( 'A target title is required for this RevDel type', 'needtarget' );
+ }
+
+ $list = RevisionDeleter::createList(
+ $params['type'], $this->getContext(), $targetObj, $params['ids']
+ );
+ $status = $list->setVisibility(
+ array( 'value' => $bitfield, 'comment' => $params['reason'], 'perItemStatus' => true )
+ );
+
+ $result = $this->getResult();
+ $data = $this->extractStatusInfo( $status );
+ $data['target'] = $targetObj->getFullText();
+ $data['items'] = array();
+
+ foreach ( $status->itemStatuses as $id => $s ) {
+ $data['items'][$id] = $this->extractStatusInfo( $s );
+ $data['items'][$id]['id'] = $id;
+ }
+
+ $list->reloadFromMaster();
+ // @codingStandardsIgnoreStart Avoid function calls in a FOR loop test part
+ for ( $item = $list->reset(); $list->current(); $item = $list->next() ) {
+ $data['items'][$item->getId()] += $item->getApiData( $this->getResult() );
+ }
+ // @codingStandardsIgnoreEnd
+
+ $data['items'] = array_values( $data['items'] );
+ $result->setIndexedTagName( $data['items'], 'i' );
+ $result->addValue( null, $this->getModuleName(), $data );
+ }
+
+ private function extractStatusInfo( $status ) {
+ $ret = array(
+ 'status' => $status->isOK() ? 'Success' : 'Fail',
+ );
+ $errors = $this->formatStatusMessages( $status->getErrorsByType( 'error' ) );
+ if ( $errors ) {
+ $this->getResult()->setIndexedTagName( $errors, 'e' );
+ $ret['errors'] = $errors;
+ }
+ $warnings = $this->formatStatusMessages( $status->getErrorsByType( 'warning' ) );
+ if ( $warnings ) {
+ $this->getResult()->setIndexedTagName( $warnings, 'w' );
+ $ret['warnings'] = $warnings;
+ }
+
+ return $ret;
+ }
+
+ private function formatStatusMessages( $messages ) {
+ if ( !$messages ) {
+ return array();
+ }
+ $result = $this->getResult();
+ $ret = array();
+ foreach ( $messages as $m ) {
+ $message = array();
+ if ( $m['message'] instanceof Message ) {
+ $msg = $m['message'];
+ $message = array( 'message' => $msg->getKey() );
+ if ( $msg->getParams() ) {
+ $message['params'] = $msg->getParams();
+ $result->setIndexedTagName( $message['params'], 'p' );
+ }
+ } else {
+ $message = array( 'message' => $m['message'] );
+ $msg = wfMessage( $m['message'] );
+ if ( isset( $m['params'] ) ) {
+ $message['params'] = $m['params'];
+ $result->setIndexedTagName( $message['params'], 'p' );
+ $msg->params( $m['params'] );
+ }
+ }
+ $message['rendered'] = $msg->useDatabase( false )->inLanguage( 'en' )->plain();
+ $ret[] = $message;
+ }
+
+ return $ret;
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'type' => array(
+ ApiBase::PARAM_TYPE => RevisionDeleter::getTypes(),
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'target' => null,
+ 'ids' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'hide' => array(
+ ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'show' => array(
+ ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'suppress' => array(
+ ApiBase::PARAM_TYPE => array( 'yes', 'no', 'nochange' ),
+ ApiBase::PARAM_DFLT => 'nochange',
+ ),
+ 'token' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'reason' => null,
+ );
+ }
+
+ public function getParamDescription() {
+ return array(
+ 'type' => 'Type of revision deletion being performed',
+ 'target' => 'Page title for the revision deletion, if required for the type',
+ 'ids' => 'Identifiers for the revisions to be deleted',
+ 'hide' => 'What to hide for each revision',
+ 'show' => 'What to unhide for each revision',
+ 'suppress' => 'Whether to suppress data from administrators as well as others',
+ 'token' => 'A delete token previously retrieved through action=tokens',
+ 'reason' => 'Reason for the deletion/undeletion',
+ );
+ }
+
+ public function getDescription() {
+ return 'Delete/undelete revisions';
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(),
+ array(
+ 'needtarget' => 'A target title is required for this RevDel type',
+ 'badparams' => 'Bad value for some parameter',
+ )
+ );
+ }
+
+ public function needsToken() {
+ return true;
+ }
+
+ public function getTokenSalt() {
+ return '';
+ }
+
+ public function getExamples() {
+ return array(
+ 'api.php?action=revisiondelete&target=Main%20Page&type=revision&ids=12345&' .
+ 'hide=content&token=123ABC'
+ => 'Hide content for revision 12345 on the Main Page',
+ 'api.php?action=revisiondelete&type=logging&ids=67890&hide=content|comment|user&' .
+ 'reason=BLP%20violation&token=123ABC'
+ => 'Hide all data on log entry 67890 with the reason "BLP violation"',
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Revisiondelete';
+ }
+}
* @ingroup API
*/
class ApiWatch extends ApiBase {
+ private $mPageSet = null;
public function execute() {
$user = $this->getUser();
if ( !$user->isLoggedIn() ) {
$this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
}
+
if ( !$user->isAllowed( 'editmywatchlist' ) ) {
$this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
}
$params = $this->extractRequestParams();
- $title = Title::newFromText( $params['title'] );
+ $pageSet = $this->getPageSet();
+ // by default we use pageset to extract the page to work on.
+ // title is still supported for backward compatibility
+ if ( !isset( $params['title'] ) ) {
+ $pageSet->execute();
+ $res = $pageSet->getInvalidTitlesAndRevisions( array(
+ 'invalidTitles',
+ 'special',
+ 'missingIds',
+ 'missingRevIds',
+ 'interwikiTitles'
+ ) );
+
+ foreach ( $pageSet->getMissingTitles() as $title ) {
+ $r = $this->watchTitle( $title, $user, $params );
+ $r['missing'] = 1;
+ $res[] = $r;
+ }
+
+ foreach ( $pageSet->getGoodTitles() as $title ) {
+ $r = $this->watchTitle( $title, $user, $params );
+ $res[] = $r;
+ }
+ $this->getResult()->setIndexedTagName( $res, 'w' );
+ } else {
+ // dont allow use of old title parameter with new pageset parameters.
+ $extraParams = array_keys( array_filter( $pageSet->extractRequestParams(), function ( $x ) {
+ return $x !== null && $x !== false;
+ } ) );
+
+ if ( $extraParams ) {
+ $p = $this->getModulePrefix();
+ $this->dieUsage(
+ "The parameter {$p}title can not be used with " . implode( ", ", $extraParams ),
+ 'invalidparammix'
+ );
+ }
+
+ $title = Title::newFromText( $params['title'] );
+ if ( !$title || !$title->isWatchable() ) {
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ }
+ $res = $this->watchTitle( $title, $user, $params, true );
+ }
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
+ }
- if ( !$title || !$title->isWatchable() ) {
- $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ private function watchTitle( Title $title, User $user, array $params,
+ $compatibilityMode = false
+ ) {
+ if ( !$title->isWatchable() ) {
+ return array( 'title' => $title->getPrefixedText(), 'watchable' => 0 );
}
$res = array( 'title' => $title->getPrefixedText() );
}
if ( $params['unwatch'] ) {
- $res['unwatched'] = '';
- $res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
- ->title( $title )->parseAsBlock();
$status = UnwatchAction::doUnwatch( $title, $user );
+ if ( $status->isOK() ) {
+ $res['unwatched'] = '';
+ $res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
+ ->title( $title )->parseAsBlock();
+ }
} else {
- $res['watched'] = '';
- $res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
- ->title( $title )->parseAsBlock();
$status = WatchAction::doWatch( $title, $user );
+ if ( $status->isOK() ) {
+ $res['watched'] = '';
+ $res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
+ ->title( $title )->parseAsBlock();
+ }
}
if ( !is_null( $oldLang ) ) {
}
if ( !$status->isOK() ) {
- $this->dieStatus( $status );
+ if ( $compatibilityMode ) {
+ $this->dieStatus( $status );
+ }
+ $res['error'] = $this->getErrorFromStatus( $status );
}
- $this->getResult()->addValue( null, $this->getModuleName(), $res );
+
+ return $res;
+ }
+
+ /**
+ * Get a cached instance of an ApiPageSet object
+ * @return ApiPageSet
+ */
+ private function getPageSet() {
+ if ( $this->mPageSet === null ) {
+ $this->mPageSet = new ApiPageSet( $this );
+ }
+
+ return $this->mPageSet;
}
public function mustBePosted() {
return 'watch';
}
- public function getAllowedParams() {
- return array(
+ public function getAllowedParams( $flags = 0 ) {
+ $result = array(
'title' => array(
ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true
+ ApiBase::PARAM_DEPRECATED => true
),
'unwatch' => false,
'uselang' => null,
ApiBase::PARAM_REQUIRED => true
),
);
+ if ( $flags ) {
+ $result += $this->getPageSet()->getFinalParams( $flags );
+ }
+
+ return $result;
}
public function getParamDescription() {
- return array(
- 'title' => 'The page to (un)watch',
+ $psModule = $this->getPageSet();
+
+ return $psModule->getParamDescription() + array(
+ 'title' => 'The page to (un)watch. use titles instead',
'unwatch' => 'If set the page will be unwatched rather than watched',
'uselang' => 'Language to show the message in',
'token' => 'A token previously acquired via prop=info',
}
public function getDescription() {
- return 'Add or remove a page from/to the current user\'s watchlist';
+ return 'Add or remove pages from/to the current user\'s watchlist';
}
public function getPossibleErrors() {
public function getExamples() {
return array(
- 'api.php?action=watch&title=Main_Page' => 'Watch the page "Main Page"',
- 'api.php?action=watch&title=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
+ 'api.php?action=watch&titles=Main_Page' => 'Watch the page "Main Page"',
+ 'api.php?action=watch&titles=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
);
}
return $text;
}
- wfDebug( __METHOD__ . "()\n", false );
+ wfDebug( __METHOD__ . "()\n", 'log' );
$now = wfTimestampNow();
if ( $this->useGzip() ) {
unset( $data[$key] );
}
}
+
// The JSON format only supports messages, none of the other variables, so wrap the data
return array( 'messages' => $data );
}
try {
$compiledRules = CLDRPluralRuleEvaluator::compile( $rules );
} catch ( CLDRPluralRuleError $e ) {
- wfDebugLog( 'l10n', $e->getMessage() . "\n" );
+ wfDebugLog( 'l10n', $e->getMessage() );
return array();
}
public function endRecentChangesList() {
$out = $this->rclistOpen ? "</ul>\n" : '';
$out .= '</div>';
+
return $out;
}
*
* @file
*/
+
class OldChangesList extends ChangesList {
/**
* Format a line using the old system (aka without any javascript).
*
* @file
*/
+
class RCCacheEntry extends RecentChange {
public $curlink;
public $difflink;
}
} catch ( RedisException $e ) {
$this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
- wfDebugLog( 'redis', "Redis exception connecting to $server: " . $e->getMessage() . "\n" );
+ wfDebugLog( 'redis', "Redis exception connecting to $server: " . $e->getMessage() );
return false;
}
* @param RedisException $e
*/
public function handleException( $server, RedisConnRef $cref, RedisException $e ) {
- wfDebugLog( 'redis', "Redis exception on server $server: " . $e->getMessage() . "\n" );
+ wfDebugLog( 'redis', "Redis exception on server $server: " . $e->getMessage() );
foreach ( $this->connections[$server] as $key => $connection ) {
if ( $cref->isConnIdentical( $connection['conn'] ) ) {
$this->idlePoolSize -= $connection['free'] ? 1 : 0;
*
* @since 1.23
*/
-
abstract class Config {
-
/**
* @param string $name configuration variable name without prefix
* @param string $prefix of the variable name
*/
public function set( $name, $value, $prefix = 'wg' ) {
$GLOBALS[$prefix . $name] = $value;
+
return Status::newGood();
}
}
*/
public function getRedirectTarget() {
list( $title, ) = $this->getRedirectTargetAndText();
+
return $title;
}
if ( $this->config === null ) {
$this->config = Config::factory();
}
+
return $this->config;
}
if ( !count( $rows ) ) {
return true; // nothing to do
}
- $rows = is_array( reset( $rows ) ) ? $rows : array( $rows );
+
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
if ( count( $uniqueIndexes ) ) {
$clauses = array(); // list WHERE clauses that each identify a single row
* @param string $delTable The table to delete from.
* @param string $joinTable The other table.
* @param string $delVar The variable to join on, in the first table.
- * @param string$joinVar The variable to join on, in the second table.
+ * @param string $joinVar The variable to join on, in the second table.
* @param array $conds Condition array of field names mapped to variables,
* ANDed together in the WHERE clause
* @param string $fname Calling function name (use __METHOD__) for logs/profiling
* @param array $join_conds
* @return string
*/
- protected function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(), $join_conds = array() ) {
+ protected function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(),
+ $join_conds = array()
+ ) {
$ret = array();
$retJOIN = array();
$use_index_safe = is_array( $use_index ) ? $use_index : array();
if ( !count( $rows ) ) {
return true; // nothing to do
}
- $rows = is_array( reset( $rows ) ) ? $rows : array( $rows );
+
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
$table = $this->tableName( $table );
$columns = array_keys( $rows[0] );
*/
protected function mysqlFieldType( $res, $n ) {
$field = $res->fetch_field_direct( $n );
+
return $field->type;
}
* can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do
* so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly.
*/
- function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array() ) {
+ function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
+ $options = array(), $join_conds = array()
+ ) {
if ( is_array( $options ) ) {
$forUpdateKey = array_search( 'FOR UPDATE', $options );
if ( $forUpdateKey !== false && $join_conds ) {
/**
* Return the next in a sequence, save the value for retrieval via insertId()
- *
+ *
* @param string $seqName
* @return int|null
*/
if ( isset( $options['FOR UPDATE'] ) ) {
$postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', $options['FOR UPDATE'] );
- } else if ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
+ } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
$postLimitTail .= ' FOR UPDATE';
}
foreach ( $lags as $i => $lag ) {
if ( $i != 0 ) {
if ( $lag === false ) {
- wfDebugLog( 'replication', "Server #$i is not replicating\n" );
+ wfDebugLog( 'replication', "Server #$i is not replicating" );
unset( $loads[$i] );
} elseif ( isset( $this->mServers[$i]['max lag'] ) && $lag > $this->mServers[$i]['max lag'] ) {
- wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)\n" );
+ wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
unset( $loads[$i] );
}
}
$i = $this->getRandomNonLagged( $currentLoads, $wiki );
if ( $i === false && count( $currentLoads ) != 0 ) {
# All slaves lagged. Switch to read-only mode
- wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode\n" );
+ wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
$wgReadOnly = 'The database has been automatically locked ' .
'while the slave database servers catch up to the master';
$i = ArrayUtils::pickRandom( $currentLoads );
# pickRandom() returned false
# This is permanent and means the configuration or the load monitor
# wants us to return false.
- wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false\n" );
+ wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false" );
return false;
}
wfDebugLog( 'connect', __METHOD__ .
- ": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
+ ": Using reader #$i: {$this->mServers[$i]['host']}..." );
$conn = $this->openConnection( $i, $wiki );
if ( !$conn ) {
- wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki\n" );
+ wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki" );
unset( $nonErrorLoads[$i] );
unset( $currentLoads[$i] );
continue;
# If all servers were down, quit now
if ( !count( $nonErrorLoads ) ) {
- wfDebugLog( 'connect', "All servers down\n" );
+ wfDebugLog( 'connect', "All servers down" );
}
if ( $i !== false ) {
* @since 1.19
* @param $msg string
* @param $callerOffset int
- * @param $level int A PHP error level. See sendWarning()
+ * @param $level int A PHP error level. See sendMessage()
* @param $log string: 'production' will always trigger a php error, 'auto'
* will trigger an error if $wgDevelopmentWarnings is true, and 'debug'
* will only write to the debug log(s).
$callerDescription = self::getCallerDescription( $callerOffset );
- self::sendWarning( $msg, $callerDescription, $level );
+ self::sendMessage( $msg, $callerDescription, 'warning', $level );
if ( self::$enabled ) {
self::$log[] = array(
if ( $sendToLog ) {
global $wgDevelopmentWarnings; // we could have a more specific $wgDeprecationWarnings setting.
- self::sendWarning(
+ self::sendMessage(
$msg,
$callerDescription,
+ 'deprecated',
$wgDevelopmentWarnings ? E_USER_DEPRECATED : false
);
}
}
/**
- * Send a warning to the debug log and optionally also trigger a PHP
+ * Send a message to the debug log and optionally also trigger a PHP
* error, depending on the $level argument.
*
* @param $msg string Message to send
* @param $caller array caller description get from getCallerDescription()
+ * @param $group string log group on which to send the message
* @param $level int|bool error level to use; set to false to not trigger an error
*/
- private static function sendWarning( $msg, $caller, $level ) {
+ private static function sendMessage( $msg, $caller, $group, $level ) {
$msg .= ' [Called from ' . $caller['func'] . ' in ' . $caller['file'] . ']';
if ( $level !== false ) {
trigger_error( $msg, $level );
}
- wfDebug( "$msg\n" );
+ wfDebugLog( $group, $msg, 'log' );
}
/**
$job = new RefreshLinksJob(
$title,
array(
- 'table' => $table,
+ 'table' => $table,
'recursive' => true,
) + Job::newRootJobParams( // "overall" refresh links job info
"refreshlinks:{$table}:{$title->getPrefixedText()}"
return;
}
- wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) . "\n" );
+ wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
if ( $wgHTCPRouting ) {
self::HTCPPurge( $urlArr );
if ( !$conn ) {
$errstr = socket_strerror( socket_last_error() );
wfDebugLog( 'squid', __METHOD__ .
- ": Error opening UDP socket: $errstr\n" );
+ ": Error opening UDP socket: $errstr" );
wfProfileOut( __METHOD__ );
return;
$conf = self::getRuleForURL( $url, $wgHTCPRouting );
if ( !$conf ) {
wfDebugLog( 'squid', __METHOD__ .
- "No HTCP rule configured for URL {$url} , skipping\n" );
+ "No HTCP rule configured for URL {$url} , skipping" );
continue;
}
$htcpTransID, $htcpSpecifier, 2 );
wfDebugLog( 'squid', __METHOD__ .
- "Purging URL $url via HTCP\n" );
+ "Purging URL $url via HTCP" );
foreach ( $conf as $subconf ) {
socket_sendto( $conn, $htcpPacket, $htcpLen, 0,
$subconf['host'], $subconf['port'] );
*/
protected $mReducedLineNumbers = false;
- /** @var string Link to action=markpatrolled */
+ /** @var string Link to action=markpatrolled */
protected $mMarkPatrolledLink = null;
/** @var bool Show rev_deleted content if allowed */
$limit = 100; // use diff-multi-manyusers if too many users
$users = $this->mNewPage->getAuthorsBetween( $oldRev, $newRev, $limit );
$numUsers = count( $users );
- if( $numUsers == 1 && $users[0] == $newRev->getRawUserText() ) {
+
+ if ( $numUsers == 1 && $users[0] == $newRev->getRawUserText() ) {
$numUsers = 0; // special case to say "by the same user" instead of "by one other user"
}
$cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
if ( isset( $externalBlobCache[$cacheID] ) ) {
wfDebugLog( 'ExternalStoreDB-cache',
- "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
+ "ExternalStoreDB::fetchBlob cache hit on $cacheID" );
return $externalBlobCache[$cacheID];
}
wfDebugLog( 'ExternalStoreDB-cache',
- "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
+ "ExternalStoreDB::fetchBlob cache miss on $cacheID" );
$dbr = $this->getSlave( $cluster );
$ret = $dbr->selectField( $this->getTable( $dbr ),
'blob_text', array( 'blob_id' => $id ), __METHOD__ );
if ( $ret === false ) {
wfDebugLog( 'ExternalStoreDB',
- "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
+ "ExternalStoreDB::fetchBlob master fallback on $cacheID" );
// Try the master
$dbw = $this->getMaster( $cluster );
$ret = $dbw->selectField( $this->getTable( $dbw ),
'blob_text', array( 'blob_id' => $id ), __METHOD__ );
if ( $ret === false ) {
wfDebugLog( 'ExternalStoreDB',
- "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
+ "ExternalStoreDB::fetchBlob master failed to find $cacheID" );
}
}
if ( $itemID !== false && $ret !== false ) {
if ( $ids ) {
wfDebugLog( __CLASS__, __METHOD__ .
" master fallback on '$cluster' for: " .
- implode( ',', array_keys( $ids ) ) . "\n" );
+ implode( ',', array_keys( $ids ) ) );
// Try the master
$dbw = $this->getMaster( $cluster );
$res = $dbw->select( $this->getTable( $dbr ),
array( 'blob_id' => array_keys( $ids ) ),
__METHOD__ );
if ( $res === false ) {
- wfDebugLog( __CLASS__, __METHOD__ . " master failed on '$cluster'\n" );
+ wfDebugLog( __CLASS__, __METHOD__ . " master failed on '$cluster'" );
} else {
$this->mergeBatchResult( $ret, $ids, $res );
}
if ( $ids ) {
wfDebugLog( __CLASS__, __METHOD__ .
" master on '$cluster' failed locating items: " .
- implode( ',', array_keys( $ids ) ) . "\n" );
+ implode( ',', array_keys( $ids ) ) );
}
return $ret;
/** @var string Path to file */
protected $path;
- /** @var string File SHA-1 in base 36 */
+ /** @var string File SHA-1 in base 36 */
protected $sha1Base36;
/**
protected $fileJournal;
/** Flags for supported features */
- const ATTR_HEADERS = 1;
+ const ATTR_HEADERS = 1;
const ATTR_METADATA = 2;
/**
*/
protected $backends = array();
- /** @var int Index of master backend */
+ /** @var int Index of master backend */
protected $masterIndex = -1;
/** @var int Bitfield */
public function getFileXAttributes( array $params ) {
$realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
return $this->backends[$this->masterIndex]->getFileXAttributes( $realParams );
}
wfProfileOut( __METHOD__ . '-miss-' . $this->name );
wfProfileOut( __METHOD__ . '-miss' );
$this->cheapCache->set( $path, 'xattr', array( 'map' => $fields, 'latest' => $latest ) );
+
return $fields;
}
*/
final protected static function normalizeXAttributes( array $xattr ) {
$newXAttr = array( 'headers' => array(), 'metadata' => array() );
+
foreach ( $xattr['headers'] as $name => $value ) {
$newXAttr['headers'][strtolower( $name )] = $value;
}
+
foreach ( $xattr['metadata'] as $name => $value ) {
$newXAttr['metadata'][strtolower( $name )] = $value;
}
+
return $newXAttr;
}
* @return Status
*/
public static function attempt( array $performOps, array $opts, FileJournal $journal ) {
- wfProfileIn( __METHOD__ );
+ $section = new ProfileSection( __METHOD__ );
$status = Status::newGood();
$n = count( $performOps );
if ( $n > self::MAX_BATCH_SIZE ) {
$status->fatal( 'backend-fail-batchsize', $n, self::MAX_BATCH_SIZE );
- wfProfileOut( __METHOD__ );
return $status;
}
$status->success[$index] = false;
++$status->failCount;
if ( !$ignoreErrors ) {
- wfProfileOut( __METHOD__ );
-
return $status; // abort
}
}
if ( count( $entries ) ) {
$subStatus = $journal->logChangeBatch( $entries, $batchId );
if ( !$subStatus->isOK() ) {
- wfProfileOut( __METHOD__ );
-
return $subStatus; // abort
}
}
// Attempt each operation (in parallel if allowed and possible)...
self::runParallelBatches( $pPerformOps, $status );
- wfProfileOut( __METHOD__ );
-
return $status;
}
* within any given sub-batch do not depend on each other.
* This will abort remaining ops on failure.
*
- * @param array $pPerformOps
+ * @param array $pPerformOps Batches of file ops (batches use original indexes)
* @param Status $status
- * @return bool Success
*/
protected static function runParallelBatches( array $pPerformOps, Status $status ) {
$aborted = false; // set to true on unexpected errors
// If attemptAsync() returns a Status, it was either due to an error
// or the backend does not support async ops and did it synchronously.
foreach ( $performOpsBatch as $i => $fileOp ) {
- if ( !$fileOp->failed() ) { // failed => already has Status
- // If the batch is just one operation, it's faster to avoid
- // pipelining as that can involve creating new TCP connections.
- $subStatus = ( count( $performOpsBatch ) > 1 )
- ? $fileOp->attemptAsync()
- : $fileOp->attempt();
+ if ( !isset( $status->success[$i] ) ) { // didn't already fail in precheck()
+ $subStatus = $fileOp->attemptAsync();
if ( $subStatus->value instanceof FileBackendStoreOpHandle ) {
$opHandles[$i] = $subStatus->value; // deferred
} else {
$statuses = $statuses + $backend->executeOpHandlesInternal( $opHandles );
// Marshall and merge all the responses (blocking)...
foreach ( $performOpsBatch as $i => $fileOp ) {
- if ( !$fileOp->failed() ) { // failed => already has Status
+ if ( !isset( $status->success[$i] ) ) { // didn't already fail in precheck()
$subStatus = $statuses[$i];
$status->merge( $subStatus );
if ( $subStatus->isOK() ) {
}
}
}
-
- return $status;
}
}
$dst = $this->resolveHashKey( $params['dst'] );
if ( $dst === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
$this->files[$dst] = array(
- 'data' => $params['content'],
+ 'data' => $params['content'],
'mtime' => wfTimestamp( TS_MW, time() )
);
$dst = $this->resolveHashKey( $params['dst'] );
if ( $dst === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
wfRestoreWarnings();
if ( $data === false ) { // source doesn't exist?
$status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
+
return $status;
}
$this->files[$dst] = array(
- 'data' => $data,
+ 'data' => $data,
'mtime' => wfTimestamp( TS_MW, time() )
);
$src = $this->resolveHashKey( $params['src'] );
if ( $src === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
$dst = $this->resolveHashKey( $params['dst'] );
if ( $dst === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
}
+
return $status;
}
$this->files[$dst] = array(
- 'data' => $this->files[$src]['data'],
+ 'data' => $this->files[$src]['data'],
'mtime' => wfTimestamp( TS_MW, time() )
);
$src = $this->resolveHashKey( $params['src'] );
if ( $src === null ) {
$status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
return $status;
}
if ( empty( $params['ignoreMissingSource'] ) ) {
$status->fatal( 'backend-fail-delete', $params['src'] );
}
+
return $status;
}
if ( isset( $this->files[$src] ) ) {
return array(
'mtime' => $this->files[$src]['mtime'],
- 'size' => strlen( $this->files[$src]['data'] ),
+ 'size' => strlen( $this->files[$src]['data'] ),
);
}
}
$tmpFiles[$srcPath] = $fsFile;
}
+
return $tmpFiles;
}
$src = $this->resolveHashKey( $params['src'] );
if ( $src === null || !isset( $this->files[$src] ) ) {
$status->fatal( 'backend-fail-stream', $params['src'] );
+
return $status;
}
return true;
}
}
+
return false;
}
}
}
}
+
return array_keys( $dirs );
}
$files[] = $relPath;
}
}
+
return $files;
}
if ( $relPath === null ) {
return null; // invalid
}
+
return ( $relPath !== '' ) ? "$fullCont/$relPath" : $fullCont;
}
}
$headers = array();
// Normalize casing, and strip out illegal headers
- if ( isset( $params['headers'] ) ) {
+ if ( isset( $params['headers'] ) ) {
foreach ( $params['headers'] as $name => $value ) {
$name = strtolower( $name );
if ( preg_match( '/^content-(type|length)$/', $name ) ) {
$contentType = $this->getContentType( $params['dst'], $params['content'], null );
$reqs = array( array(
- 'method' => 'PUT',
- 'url' => array( $dstCont, $dstRel ),
+ 'method' => 'PUT',
+ 'url' => array( $dstCont, $dstRel ),
'headers' => array(
- 'content-length' => strlen( $params['content'] ),
- 'etag' => md5( $params['content'] ),
- 'content-type' => $contentType,
+ 'content-length' => strlen( $params['content'] ),
+ 'etag' => md5( $params['content'] ),
+ 'content-type' => $contentType,
'x-object-meta-sha1base36' => $sha1Hash
) + $this->sanitizeHdrs( $params ),
- 'body' => $params['content']
+ 'body' => $params['content']
) );
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
$sha1Hash = wfBaseConvert( $sha1Hash, 16, 36, 31 );
$contentType = $this->getContentType( $params['dst'], null, $params['src'] );
- $handle = fopen( $params['src'], 'rb+' );
+ $handle = fopen( $params['src'], 'rb' );
if ( $handle === false ) { // source doesn't exist?
$status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
}
$reqs = array( array(
- 'method' => 'PUT',
- 'url' => array( $dstCont, $dstRel ),
+ 'method' => 'PUT',
+ 'url' => array( $dstCont, $dstRel ),
'headers' => array(
- 'content-length' => filesize( $params['src'] ),
- 'etag' => md5_file( $params['src'] ),
- 'content-type' => $contentType,
+ 'content-length' => filesize( $params['src'] ),
+ 'etag' => md5_file( $params['src'] ),
+ 'content-type' => $contentType,
'x-object-meta-sha1base36' => $sha1Hash
) + $this->sanitizeHdrs( $params ),
- 'body' => $handle // resource
+ 'body' => $handle // resource
) );
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
}
$reqs = array( array(
- 'method' => 'PUT',
- 'url' => array( $dstCont, $dstRel ),
+ 'method' => 'PUT',
+ 'url' => array( $dstCont, $dstRel ),
'headers' => array(
'x-copy-from' => '/' . rawurlencode( $srcCont ) .
'/' . str_replace( "%2F", "/", rawurlencode( $srcRel ) )
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
$reqs = array(
array(
- 'method' => 'PUT',
- 'url' => array( $dstCont, $dstRel ),
+ 'method' => 'PUT',
+ 'url' => array( $dstCont, $dstRel ),
'headers' => array(
'x-copy-from' => '/' . rawurlencode( $srcCont ) .
'/' . str_replace( "%2F", "/", rawurlencode( $srcRel ) )
);
if ( "{$srcCont}/{$srcRel}" !== "{$dstCont}/{$dstRel}" ) {
$reqs[] = array(
- 'method' => 'DELETE',
- 'url' => array( $srcCont, $srcRel ),
+ 'method' => 'DELETE',
+ 'url' => array( $srcCont, $srcRel ),
'headers' => array()
);
}
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $request['method'] === 'PUT' && $rcode === 201 ) {
// good
return $status;
}
- $reqs = array(
- array(
- 'method' => 'DELETE',
- 'url' => array( $srcCont, $srcRel ),
- 'headers' => array()
+ $reqs = array( array(
+ 'method' => 'DELETE',
+ 'url' => array( $srcCont, $srcRel ),
+ 'headers' => array()
) );
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 204 ) {
// good
$customHdrs = $this->sanitizeHdrs( $params ) + $stat['xattr']['headers'];
$reqs = array( array(
- 'method' => 'POST',
- 'url' => array( $srcCont, $srcRel ),
+ 'method' => 'POST',
+ 'url' => array( $srcCont, $srcRel ),
'headers' => $metaHdrs + $customHdrs
) );
$be = $this;
$method = __METHOD__;
- $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 202 ) {
// good
return $status; // already there
} elseif ( $stat === null ) {
$status->fatal( 'backend-fail-internal', $this->name );
+
return $status;
}
return $status; // ok, nothing to do
} elseif ( !is_array( $stat ) ) {
$status->fatal( 'backend-fail-internal', $this->name );
+
return $status;
}
// (b) Check the file
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'HEAD',
- 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
+ 'method' => 'HEAD',
+ 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
'headers' => $this->authTokenHeaders( $auth ) + $this->headersFromParams( $params )
) );
if ( $rcode === 200 || $rcode === 204 ) {
// Convert various random Swift dates to TS_MW
'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
// Empty objects actually return no content-length header in Ceph
- 'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
- 'sha1' => $rhdrs[ 'x-object-meta-sha1base36'],
- 'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
+ 'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
+ 'sha1' => $rhdrs['x-object-meta-sha1base36'],
+ 'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )
);
} elseif ( $rcode === 404 ) {
protected function convertSwiftDate( $ts, $format = TS_MW ) {
try {
$timestamp = new MWTimestamp( $ts );
+
return $timestamp->getTimestamp( $format );
} catch ( MWException $e ) {
throw new FileBackendError( $e->getMessage() );
$auth = $this->getAuthentication();
if ( !$auth ) {
$objHdrs['x-object-meta-sha1base36'] = false;
+
return $objHdrs; // failed
}
$objHdrs['x-object-meta-sha1base36'] = $hash;
list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $path );
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'POST',
- 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
+ 'method' => 'POST',
+ 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
'headers' => $this->authTokenHeaders( $auth ) + $objHdrs
) );
if ( $rcode >= 200 && $rcode <= 299 ) {
$handle = fopen( 'php://temp', 'wb' );
if ( $handle ) {
$reqs[$path] = array(
- 'method' => 'GET',
- 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
+ 'method' => 'GET',
+ 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
'headers' => $this->authTokenHeaders( $auth )
+ $this->headersFromParams( $params ),
- 'stream' => $handle,
+ 'stream' => $handle,
);
} else {
$data = false;
if ( $status->isOk() ) {
return ( count( $status->value ) );
}
+
return null; // error
}
$dirs[] = $object; // directories end in '/'
}
}
- // Recursive: list all dirs under $dir and its subdirs
} else {
- $getParentDir = function( $path ) {
+ // Recursive: list all dirs under $dir and its subdirs
+ $getParentDir = function ( $path ) {
return ( strpos( $path, '/' ) !== false ) ? dirname( $path ) : false;
};
+
// Get directory from last item of prior page
$lastDir = $getParentDir( $after ); // must be first page
$status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix );
+
if ( !$status->isOk() ) {
return $dirs; // error
}
+
$objects = $status->value;
+
foreach ( $objects as $object ) { // files
$objectDir = $getParentDir( $object ); // directory of object
+
if ( $objectDir !== false && $objectDir !== $dir ) {
// Swift stores paths in UTF-8, using binary sorting.
// See function "create_container_table" in common/db.py.
} else {
$status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix, '/' );
}
- // Recursive: list all files under $dir and its subdirs
} else {
+ // Recursive: list all files under $dir and its subdirs
if ( !empty( $params['adviseStat'] ) ) {
$status = $this->objectListing( $fullCont, 'info', $limit, $after, $prefix );
} else {
$status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix );
}
}
+
// Reformat this list into a list of (name, stat array or null) entries
if ( !$status->isOk() ) {
return $files; // error
}
+
$objects = $status->value;
$files = $this->buildFileObjectListing( $params, $dir, $objects );
+
// Page on the unfiltered object listing (what is returned may be filtered)
if ( count( $objects ) < $limit ) {
$after = INF; // avoid a second RTT
}
$stat = array(
// Convert various random Swift dates to TS_MW
- 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
- 'size' => (int)$object->bytes,
- 'md5' => ctype_xdigit( $object->hash ) ? $object->hash : null,
+ 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
+ 'size' => (int)$object->bytes,
+ 'md5' => ctype_xdigit( $object->hash ) ? $object->hash : null,
'latest' => false // eventually consistent
);
$names[] = array( $object->name, $stat );
$this->clearCache( array( $params['src'] ) );
$stat = $this->getFileStat( $params );
}
+
return $stat['xattr'];
} else {
return false;
$auth = $this->getAuthentication();
if ( !$auth || !is_array( $this->getContainerStat( $srcCont ) ) ) {
$status->fatal( 'backend-fail-stream', $params['src'] );
+
return $status;
}
$handle = fopen( 'php://output', 'wb' );
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'GET',
- 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
+ 'method' => 'GET',
+ 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
'headers' => $this->authTokenHeaders( $auth )
+ $this->headersFromParams( $params ),
- 'stream' => $handle,
+ 'stream' => $handle,
) );
if ( $rcode >= 200 && $rcode <= 299 ) {
$handle = fopen( $tmpFile->getPath(), 'wb' );
if ( $handle ) {
$reqs[$path] = array(
- 'method' => 'GET',
- 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
+ 'method' => 'GET',
+ 'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
'headers' => $this->authTokenHeaders( $auth )
+ $this->headersFromParams( $params ),
- 'stream' => $handle,
+ 'stream' => $handle,
);
} else {
$tmpFile = null;
"GET\n{$expires}\n{$contPath}/{$srcRel}",
$this->swiftTempUrlKey
);
+
return "{$url}?temp_url_sig={$signature}&temp_url_expires={$expires}";
} else { // give S3 API URL for rgw
// Path for signature starts with the bucket
foreach ( $fileOpHandles as $index => $fileOpHandle ) {
$statuses[$index] = Status::newFatal( 'backend-fail-connect', $this->name );
}
+
return $statuses;
}
}
// Run all requests for the first stage, then the next, and so on
- for ( $stage = 0; $stage < count( $httpReqsByStage ); ++$stage ) {
+ $reqCount = count( $httpReqsByStage );
+ for ( $stage = 0; $stage < $reqCount; ++$stage ) {
$httpReqs = $this->http->runMulti( $httpReqsByStage[$stage] );
foreach ( $httpReqs as $index => $httpReq ) {
// Run the callback for each request of this operation
*/
protected function setContainerAccess( $container, array $readGrps, array $writeGrps ) {
$status = Status::newGood();
-
$auth = $this->getAuthentication();
+
if ( !$auth ) {
$status->fatal( 'backend-fail-connect', $this->name );
+
return $status;
}
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'POST',
- 'url' => $this->storageUrl( $auth, $container ),
+ 'method' => 'POST',
+ 'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth ) + array(
- 'x-container-read' => implode( ',', $readGrps ),
+ 'x-container-read' => implode( ',', $readGrps ),
'x-container-write' => implode( ',', $writeGrps )
)
) );
}
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'HEAD',
- 'url' => $this->storageUrl( $auth, $container ),
+ 'method' => 'HEAD',
+ 'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth )
) );
} else {
$this->onError( null, __METHOD__,
array( 'cont' => $container ), $rerr, $rcode, $rdesc );
+
return null;
}
}
$auth = $this->getAuthentication();
if ( !$auth ) {
$status->fatal( 'backend-fail-connect', $this->name );
+
return $status;
}
$writeGrps = array( $this->swiftUser ); // sanity
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'PUT',
- 'url' => $this->storageUrl( $auth, $container ),
+ 'method' => 'PUT',
+ 'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth ) + array(
- 'x-container-read' => implode( ',', $readGrps ),
+ 'x-container-read' => implode( ',', $readGrps ),
'x-container-write' => implode( ',', $writeGrps )
)
) );
$auth = $this->getAuthentication();
if ( !$auth ) {
$status->fatal( 'backend-fail-connect', $this->name );
+
return $status;
}
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'DELETE',
- 'url' => $this->storageUrl( $auth, $container ),
+ 'method' => 'DELETE',
+ 'url' => $this->storageUrl( $auth, $container ),
'headers' => $this->authTokenHeaders( $auth )
) );
$auth = $this->getAuthentication();
if ( !$auth ) {
$status->fatal( 'backend-fail-connect', $this->name );
+
return $status;
}
}
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'GET',
- 'url' => $this->storageUrl( $auth, $fullCont ),
- 'query' => $query,
+ 'method' => 'GET',
+ 'url' => $this->storageUrl( $auth, $fullCont ),
+ 'query' => $query,
'headers' => $this->authTokenHeaders( $auth )
) );
$this->authSessionTimestamp = time() - ceil( $this->authTTL / 2 );
} else { // cache miss
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
- 'method' => 'GET',
- 'url' => "{$this->swiftAuthUrl}/v1.0",
+ 'method' => 'GET',
+ 'url' => "{$this->swiftAuthUrl}/v1.0",
'headers' => array(
- 'x-auth-user' => $this->swiftUser, 'x-auth-key' => $this->swiftKey )
+ 'x-auth-user' => $this->swiftUser,
+ 'x-auth-key' => $this->swiftKey
+ )
) );
if ( $rcode >= 200 && $rcode <= 299 ) { // OK
$this->authCreds = array(
- 'auth_token' => $rhdrs['x-auth-token'],
+ 'auth_token' => $rhdrs['x-auth-token'],
'storage_url' => $rhdrs['x-storage-url']
);
$this->authSessionTimestamp = time();
} elseif ( $rcode === 401 ) {
$this->onError( null, __METHOD__, array(), "Authentication failed.", $rcode );
$this->authErrorTimestamp = time();
+
return null;
} else {
$this->onError( null, __METHOD__, array(), "HTTP return code: $rcode", $rcode );
$this->authErrorTimestamp = time();
+
return null;
}
}
}
+
return $this->authCreds;
}
if ( strlen( $object ) ) {
$parts[] = str_replace( "%2F", "/", rawurlencode( $object ) );
}
+
return implode( '/', $parts );
}
foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
if ( !$this->isServerUp( $lockSrv ) ) {
$status->warning( 'lockmanager-fail-svr-release', $lockSrv );
- // Attempt to release the lock on this peer
} else {
+ // Attempt to release the lock on this peer
$status->merge( $this->freeLocksOnServer( $lockSrv, $pathsByType ) );
++$yesVotes; // success for this peer
// Normally the first peers form the quorum, and the others are ignored.
/** @var Array Map of zones to config */
protected $zones = array();
- /** @var string URL of thumb.php */
+ /** @var string URL of thumb.php */
protected $thumbScriptUrl;
/** @var bool Whether to skip media file transformation on parse and rely
*/
protected $abbrvThreshold;
- /** @var string The URL of the repo's favicon, if any */
+ /** @var string The URL of the repo's favicon, if any */
protected $favicon;
/**
$searchName = File::normalizeTitle( $title )->getDBkey(); // must be valid
if ( $flags & self::NAME_AND_TIME_ONLY ) {
$result[$searchName] = array(
- 'title' => $file->getTitle()->getDBkey(),
+ 'title' => $file->getTitle()->getDBkey(),
'timestamp' => $file->getTimestamp()
);
} else {
/** @var int Redownload thumbnail files after a month (86400*30) */
protected $fileCacheExpiry = 2592000;
- /** @var array */
+ /** @var array */
protected $mFileExists = array();
- /** @var array */
+ /** @var array */
private $mQueryCache = array();
/**
}
}
- $fileMatchesSearch = function( File $file, array $search ) {
+ $fileMatchesSearch = function ( File $file, array $search ) {
// Note: file name comparison done elsewhere (to handle redirects)
$user = ( !empty( $search['private'] ) && $search['private'] instanceof User )
? $search['private']
: null;
+
return (
$file->exists() &&
(
};
$repo = $this;
- $applyMatchingFiles = function( ResultWrapper $res, &$searchSet, &$finalFiles )
+ $applyMatchingFiles = function ( ResultWrapper $res, &$searchSet, &$finalFiles )
use ( $repo, $fileMatchesSearch, $flags )
{
global $wgContLang;
$dbKeysLook[] = $wgContLang->lcfirst( $file->getName() );
}
foreach ( $dbKeysLook as $dbKey ) {
- if ( isset( $searchSet[$dbKey])
+ if ( isset( $searchSet[$dbKey] )
&& $fileMatchesSearch( $file, $searchSet[$dbKey] )
) {
$finalFiles[$dbKey] = ( $flags & FileRepo::NAME_AND_TIME_ONLY )
foreach ( array_keys( $searchSet ) as $dbKey ) {
$imgNames[] = $this->getNameFromTitle( File::normalizeTitle( $dbKey ) );
}
+
if ( count( $imgNames ) ) {
$res = $dbr->select( 'image',
LocalFile::selectFields(), array( 'img_name' => $imgNames ), __METHOD__ );
);
}
}
+
if ( count( $oiConds ) ) {
$res = $dbr->select( 'oldimage',
OldLocalFile::selectFields(), $dbr->makeList( $oiConds, LIST_OR ), __METHOD__ );
if ( !empty( $search['ignoreRedirect'] ) ) {
continue;
}
+
$title = File::normalizeTitle( $dbKey );
$redir = $this->checkRedirect( $title ); // hopefully hits memcached
+
if ( $redir && $redir->getNamespace() == NS_FILE ) {
$file = $this->newFile( $redir );
if ( $file && $fileMatchesSearch( $file, $search ) ) {
$file->redirectedFrom( $title->getDBkey() );
if ( $flags & FileRepo::NAME_AND_TIME_ONLY ) {
$finalFiles[$dbKey] = array(
- 'title' => $file->getTitle()->getDBkey(),
+ 'title' => $file->getTitle()->getDBkey(),
'timestamp' => $file->getTimestamp()
);
} else {
*/
function getInfo() {
global $wgFavicon;
+
return array_merge( parent::getInfo(), array(
'favicon' => wfExpandUrl( $wgFavicon ),
) );
/** @var array */
protected $foreignInfo;
- /** @var ProcessCacheLRU */
+ /** @var ProcessCacheLRU */
protected $cache;
/** @var RepoGroup */
}
throw new MWException( "Unknown type '$type'." );
-
}
/**
/** @var Title|string|bool */
protected $title;
- /** @var string Text of last error */
+ /** @var string Text of last error */
protected $lastError;
- /** @var string Main part of the title, with underscores (Title::getDBkey) */
+ /** @var string Main part of the title, with underscores (Title::getDBkey) */
protected $redirected;
/** @var Title */
if ( !$handler ) {
return false;
}
+
return $handler->getCommonMetaArray( $this );
}
$this->assertRepoDefined();
return $this->repo->getZonePath( 'thumb' ) . '/' .
- $this->getArchiveThumbRel( $archiveName, $suffix );
+ $this->getArchiveThumbRel( $archiveName, $suffix );
}
/**
/** @var array List of file IDs to restore */
private $ids;
- /** @var bool Add all revisions of the file */
+ /** @var bool Add all revisions of the file */
private $all;
- /** @var bool Wether to remove all settings for suppressed fields */
+ /** @var bool Wether to remove all settings for suppressed fields */
private $unsuppress = false;
/**
/** @var Title */
protected $target;
- /** @var */
protected $cur;
- /** @var */
protected $olds;
- /** @var */
protected $oldCount;
- /** @var */
protected $archive;
/** @var DatabaseBase */
* @ingroup FileAbstraction
*/
class UnregisteredLocalFile extends File {
- /** @var Title */
+ /** @var Title */
protected $title;
/** @var string */
* @ingroup Media
*/
abstract class ImageGalleryBase extends ContextSource {
- /** @var array Gallery images */
+ /** @var array Gallery images */
protected $mImages;
- /** @var bool Whether to show the filesize in bytes in categories */
+ /** @var bool Whether to show the filesize in bytes in categories */
protected $mShowBytes;
/** @var bool Whether to show the filename. Default: true */
* @param string $html Additional HTML text to be shown. The name and size
* of the image are always shown.
* @param string $alt Alt text for the image
- * @param string $link Override image link (optional)
+ * @param string $link Override image link (optional)
* @param array $handlerOpts Array of options for image handler (aka page number)
*/
function insert( $title, $html = '', $alt = '', $link = '', $handlerOpts = array() ) {
if ( $this->isVForm() ) {
// mw-ui-block is necessary because the buttons aren't necessarily in an
// immediate child div of the vform.
- // TODO Let client specify if the primary submit button is progressive or destructive
- array_push( $attribs['class'], 'mw-ui-button', 'mw-ui-big', 'mw-ui-constructive', 'mw-ui-block' );
+ // @todo Let client specify if the primary submit button is progressive or destructive
+ array_push(
+ $attribs['class'],
+ 'mw-ui-button',
+ 'mw-ui-big',
+ 'mw-ui-constructive',
+ 'mw-ui-block'
+ );
}
$html .= Xml::submitButton( $this->getSubmitText(), $attribs ) . "\n";
$ret = array();
- foreach( $list as $key ) {
+ foreach ( $list as $key ) {
if ( in_array( $key, $boolAttribs ) ) {
if ( !empty( $this->mParams[$key] ) ) {
$ret[$key] = '';
if ( !$status->isOK() ) {
return $status;
}
- $status->value->insert( 'site_stats', array(
- 'ss_row_id' => 1,
- 'ss_total_views' => 0,
- 'ss_total_edits' => 0,
- 'ss_good_articles' => 0,
- 'ss_total_pages' => 0,
- 'ss_users' => 0,
- 'ss_images' => 0 ),
- __METHOD__, 'IGNORE' );
+ $status->value->insert(
+ 'site_stats',
+ array(
+ 'ss_row_id' => 1,
+ 'ss_total_views' => 0,
+ 'ss_total_edits' => 0,
+ 'ss_good_articles' => 0,
+ 'ss_total_pages' => 0,
+ 'ss_users' => 0,
+ 'ss_images' => 0
+ ),
+ __METHOD__, 'IGNORE'
+ );
return Status::newGood();
}
}
if ( $this->groupPermissions['*']['edit'] === false
&& $this->groupPermissions['*']['createaccount'] === false
- && $this->groupPermissions['*']['read'] !== false ) {
+ && $this->groupPermissions['*']['read'] !== false
+ ) {
$noFollow = "\n# Set \$wgNoFollowLinks to true if you open up your wiki to editing by\n"
. "# the general public and wish to apply nofollow to external links as a\n"
. "# deterrent to spammers. Nofollow is not a comprehensive anti-spam solution\n"
* @since 1.17
*/
class MysqlUpdater extends DatabaseUpdater {
-
protected function getCoreUpdateList() {
return array(
array( 'disableContentHandlerUseDB' ),
// 1.23
array( 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ),
- array( 'addIndex', 'logging', 'log_user_text_type_time', 'patch-logging_user_text_type_time_index.sql' ),
- array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
+ array( 'addIndex', 'logging', 'log_user_text_type_time',
+ 'patch-logging_user_text_type_time_index.sql' ),
+ array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
array( 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ),
);
}
'patch-ufg_group-length-increase-255.sql' ),
//1.23
- array( 'addIndex', 'logging', 'i06', 'patch-logging_user_text_type_time_index.sql' ),
- array( 'addIndex', 'logging', 'i07', 'patch-logging_user_text_time_index.sql' ),
+ array( 'addIndex', 'logging', 'i06', 'patch-logging_user_text_type_time_index.sql' ),
+ array( 'addIndex', 'logging', 'i07', 'patch-logging_user_text_time_index.sql' ),
// KEEP THIS AT THE BOTTOM!!
array( 'doRebuildDuplicateFunction' ),
* @ingroup Deployment
* @since 1.17
*/
-
class PostgresUpdater extends DatabaseUpdater {
/**
array( 'addPgIndex', 'job', 'job_cmd_token', '(job_cmd, job_token, job_random)' ),
array( 'addPgIndex', 'job', 'job_cmd_token_id', '(job_cmd, job_token, job_id)' ),
array( 'addPgIndex', 'filearchive', 'fa_sha1', '(fa_sha1)' ),
- array( 'addPgIndex', 'logging', 'logging_user_text_type_time', '(log_user_text, log_type, log_timestamp)' ),
+ array( 'addPgIndex', 'logging', 'logging_user_text_type_time',
+ '(log_user_text, log_type, log_timestamp)' ),
array( 'addPgIndex', 'logging', 'logging_user_text_time', '(log_user_text, log_timestamp)' ),
array( 'checkIndex', 'pagelink_unique', array(
// 1.23
array( 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ),
- array( 'addIndex', 'logging', 'log_user_text_type_time', 'patch-logging_user_text_type_time_index.sql' ),
- array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
+ array( 'addIndex', 'logging', 'log_user_text_type_time',
+ 'patch-logging_user_text_type_time_index.sql' ),
+ array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
array( 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ),
);
}
) {
// JS appears to be the only method that works consistently with IE7+
$this->addHtml( "\n<script>jQuery( function () { document.location = " .
- Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
+ Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
} else {
$this->parent->request->response()->header( "Refresh: 0;url=$lsUrl" );
}
// Push ready delayed jobs into the queue every 10 jobs to spread the load.
// This is also done as a periodic task, but we don't want too much done at once.
if ( $this->checkDelay && mt_rand( 0, 9 ) == 0 ) {
- $this->releaseReadyDelayedJobs();
+ $this->recyclePruneAndUndelayJobs();
}
$conn = $this->getConnection();
if ( $this->claimTTL > 0 ) {
// Keep the claimed job list down for high-traffic queues
if ( mt_rand( 0, 99 ) == 0 ) {
- $this->recycleAndDeleteStaleJobs();
+ $this->recyclePruneAndUndelayJobs();
}
$blob = $this->popAndAcquireBlob( $conn );
} else {
continue;
}
- // If $item is invalid, recycleAndDeleteStaleJobs() will cleanup as needed
+ // If $item is invalid, recyclePruneAndUndelayJobs() will cleanup as needed
$job = $this->getJobFromFields( $item ); // may be false
} while ( !$job ); // job may be false if invalid
} catch ( RedisException $e ) {
}
}
- /**
- * Release any ready delayed jobs into the queue
- *
- * @return int Number of jobs released
- * @throws JobQueueError
- */
- public function releaseReadyDelayedJobs() {
- $count = 0;
-
- $conn = $this->getConnection();
- try {
- static $script =
-<<<LUA
- local kDelayed, kUnclaimed = unpack(KEYS)
- -- Get the list of ready delayed jobs, sorted by readiness
- local ids = redis.call('zRangeByScore',kDelayed,0,ARGV[1])
- -- Migrate the jobs from the "delayed" set to the "unclaimed" list
- for k,id in ipairs(ids) do
- redis.call('lPush',kUnclaimed,id)
- redis.call('zRem',kDelayed,id)
- end
- return #ids
-LUA;
- $count += (int)$conn->luaEval( $script,
- array(
- $this->getQueueKey( 'z-delayed' ), // KEYS[1]
- $this->getQueueKey( 'l-unclaimed' ), // KEYS[2]
- time() // ARGV[1]; max "delay until" UNIX timestamp
- ),
- 2 # first two arguments are keys
- );
- } catch ( RedisException $e ) {
- $this->throwRedisException( $this->server, $conn, $e );
- }
-
- return $count;
- }
-
/**
* Recycle or destroy any jobs that have been claimed for too long
+ * and release any ready delayed jobs into the queue
*
- * @return int Number of jobs recycled/deleted
+ * @return int Number of jobs recycled/deleted/undelayed
* @throws MWException|JobQueueError
*/
- public function recycleAndDeleteStaleJobs() {
- if ( $this->claimTTL <= 0 ) { // sanity
- throw new MWException( "Cannot recycle jobs since acknowledgements are disabled." );
- }
+ public function recyclePruneAndUndelayJobs() {
$count = 0;
// For each job item that can be retried, we need to add it back to the
// main queue and remove it from the list of currenty claimed job items.
$now = time();
static $script =
<<<LUA
- local kClaimed, kAttempts, kUnclaimed, kData, kAbandoned = unpack(KEYS)
- local released,abandoned,pruned = 0,0,0
+ local kClaimed, kAttempts, kUnclaimed, kData, kAbandoned, kDelayed = unpack(KEYS)
+ local released,abandoned,pruned,undelayed = 0,0,0,0
-- Get all non-dead jobs that have an expired claim on them.
-- The score for each item is the last claim timestamp (UNIX).
local staleClaims = redis.call('zRangeByScore',kClaimed,0,ARGV[1])
redis.call('hDel',kData,id)
pruned = pruned + 1
end
- return {released,abandoned,pruned}
+ -- Get the list of ready delayed jobs, sorted by readiness (UNIX timestamp)
+ local ids = redis.call('zRangeByScore',kDelayed,0,ARGV[4])
+ -- Migrate the jobs from the "delayed" set to the "unclaimed" list
+ for k,id in ipairs(ids) do
+ redis.call('lPush',kUnclaimed,id)
+ redis.call('zRem',kDelayed,id)
+ end
+ undelayed = #ids
+ return {released,abandoned,pruned,undelayed}
LUA;
$res = $conn->luaEval( $script,
array(
$this->getQueueKey( 'l-unclaimed' ), # KEYS[3]
$this->getQueueKey( 'h-data' ), # KEYS[4]
$this->getQueueKey( 'z-abandoned' ), # KEYS[5]
+ $this->getQueueKey( 'z-delayed' ), # KEYS[6]
$now - $this->claimTTL, # ARGV[1]
$now - self::MAX_AGE_PRUNE, # ARGV[2]
- $this->maxTries # ARGV[3]
+ $this->maxTries, # ARGV[3]
+ $now # ARGV[4]
),
- 5 # number of first argument(s) that are keys
+ 6 # number of first argument(s) that are keys
);
if ( $res ) {
- list( $released, $abandoned, $pruned ) = $res;
- $count += $released + $pruned;
+ list( $released, $abandoned, $pruned, $undelayed ) = $res;
+ $count += $released + $pruned + $undelayed;
JobQueue::incrStats( 'job-recycle', $this->type, $released );
JobQueue::incrStats( 'job-abandon', $this->type, $abandoned );
}
* @return array
*/
protected function doGetPeriodicTasks() {
- $tasks = array();
+ $periods = array( 3600 ); // standard cleanup (useful on config change)
if ( $this->claimTTL > 0 ) {
- $tasks['recycleAndDeleteStaleJobs'] = array(
- 'callback' => array( $this, 'recycleAndDeleteStaleJobs' ),
- 'period' => ceil( $this->claimTTL / 2 )
- );
+ $periods[] = ceil( $this->claimTTL / 2 ); // avoid bad timing
}
if ( $this->checkDelay ) {
- $tasks['releaseReadyDelayedJobs'] = array(
- 'callback' => array( $this, 'releaseReadyDelayedJobs' ),
- 'period' => 300 // 5 minutes
- );
+ $periods[] = 300; // 5 minutes
}
-
- return $tasks;
+ return array(
+ 'recyclePruneAndUndelayJobs' => array(
+ 'callback' => array( $this, 'recyclePruneAndUndelayJobs' ),
+ 'period' => max( min( $periods ), 30 ) // sanity
+ )
+ );
}
/**
}
$dbw = wfGetDB( DB_MASTER );
- $timestamp = $dbw->timestamp();
- // Don't invalidated pages that were already invalidated
- $touchedCond = isset( $this->params['rootJobTimestamp'] )
- ? array( "page_touched < " .
- $dbw->addQuotes( $dbw->timestamp( $this->params['rootJobTimestamp'] ) ) )
- : array();
+ // The page_touched field will need to be bumped for these pages.
+ // Only bump it to the present time if no "rootJobTimestamp" was known.
+ // If it is known, it can be used instead, which avoids invalidating output
+ // that was in fact generated *after* the relevant dependency change time
+ // (e.g. template edit). This is particularily useful since refreshLinks jobs
+ // save back parser output and usually run along side htmlCacheUpdate jobs;
+ // their saved output would be invalidated by using the current timestamp.
+ if ( isset( $this->params['rootJobTimestamp'] ) ) {
+ $touchTimestamp = $this->params['rootJobTimestamp'];
+ } else {
+ $touchTimestamp = wfTimestampNow();
+ }
// Update page_touched (skipping pages already touched since the root job).
// Check $wgUpdateRowsPerQuery for sanity; batch jobs are sized by that already.
foreach ( array_chunk( $pageIds, $wgUpdateRowsPerQuery ) as $batch ) {
$dbw->update( 'page',
- array( 'page_touched' => $timestamp ),
- array( 'page_id' => $batch ) + $touchedCond,
+ array( 'page_touched' => $dbw->timestamp( $touchTimestamp ) ),
+ array( 'page_id' => $batch,
+ // don't invalidated pages that were already invalidated
+ "page_touched < " . $dbw->addQuotes( $dbw->timestamp( $touchTimestamp ) )
+ ),
__METHOD__
);
}
$titleArray = TitleArray::newFromResult( $dbw->select(
'page',
array( 'page_namespace', 'page_title' ),
- array( 'page_id' => $pageIds, 'page_touched' => $timestamp ),
+ array( 'page_id' => $pageIds, 'page_touched' => $dbw->timestamp( $touchTimestamp ) ),
__METHOD__
) );
}
/**
- * Gets the luser provided comment
+ * Gets the user provided comment
* @return string HTML
*/
public function getComment() {
}
if ( $action === true ) {
- wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n" );
+ wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)" );
} elseif ( $action === false ) {
- wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n" );
+ wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)" );
} elseif ( $action === null ) {
- wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n" );
+ wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)" );
} else {
- wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n" );
+ wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')" );
}
}
}
$class = ucfirst( __CLASS__ );
if ( $io ) {
- wfDebugLog( $this->log, "$class::$fname: begin processing: '{$this->basename}'\n" );
+ wfDebugLog( $this->log, "$class::$fname: begin processing: '{$this->basename}'" );
} else {
- wfDebugLog( $this->log, "$class::$fname: end processing: '{$this->basename}'\n" );
+ wfDebugLog( $this->log, "$class::$fname: end processing: '{$this->basename}'" );
}
}
}
* Log a fatal error
*/
protected function logError( $msg ) {
- wfDebugLog( 'redis', "Redis error: $msg\n" );
+ wfDebugLog( 'redis', "Redis error: $msg" );
}
/**
// Get core test suites
$testModules = array();
- $testModules['qunit'] = include "$IP/tests/qunit/QUnitTestResources.php";
+ $testModules['qunit'] = array();
// Get other test suites (e.g. from extensions)
wfRunHooks( 'ResourceLoaderTestModules', array( &$testModules, &$this ) );
// on document-ready, it will run once and finish. If some tests arrive
// later (possibly after QUnit has already finished) they will be ignored.
$module['position'] = 'top';
- $module['dependencies'][] = 'mediawiki.tests.qunit.testrunner';
+ $module['dependencies'][] = 'test.mediawiki.qunit.testrunner';
}
+ $testModules['qunit'] = ( include "$IP/tests/qunit/QUnitTestResources.php" ) + $testModules['qunit'];
+
foreach ( $testModules as $id => $names ) {
// Register test modules
$this->register( $testModules[$id] );
}
return "<li>$difflink $revlink $userlink $comment</li>";
}
+
+ public function getApiData( ApiResult $result ) {
+ $rev = $this->revision;
+ $user = $this->list->getUser();
+ $ret = array(
+ 'id' => $rev->getId(),
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $rev->getTimestamp() ),
+ );
+ $ret += $rev->isDeleted( Revision::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+ $ret += $rev->isDeleted( Revision::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+ $ret += $rev->isDeleted( Revision::DELETED_TEXT ) ? array( 'texthidden' => '' ) : array();
+ if ( $rev->userCan( Revision::DELETED_USER, $user ) ) {
+ $ret += array(
+ 'userid' => $rev->getUser( Revision::FOR_THIS_USER ),
+ 'user' => $rev->getUserText( Revision::FOR_THIS_USER ),
+ );
+ }
+ if ( $rev->userCan( Revision::DELETED_COMMENT, $user ) ) {
+ $ret += array(
+ 'comment' => $rev->getComment( Revision::FOR_THIS_USER ),
+ );
+ }
+ return $ret;
+ }
}
/**
return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' .
$data . ' ' . $this->getComment() . '</li>';
}
+
+ public function getApiData( ApiResult $result ) {
+ $file = $this->file;
+ $user = $this->list->getUser();
+ $ret = array(
+ 'title' => $this->list->title->getPrefixedText(),
+ 'archivename' => $file->getArchiveName(),
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() ),
+ 'width' => $file->getWidth(),
+ 'height' => $file->getHeight(),
+ 'size' => $file->getSize(),
+ );
+ $ret += $file->isDeleted( Revision::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+ $ret += $file->isDeleted( Revision::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+ $ret += $this->isDeleted() ? array( 'contenthidden' => '' ) : array();
+ if ( !$this->isDeleted() ) {
+ $ret += array(
+ 'url' => $file->getUrl(),
+ );
+ } elseif ( $this->canViewContent() ) {
+ $ret += array(
+ 'url' => SpecialPage::getTitleFor( 'Revisiondelete' )->getLinkURL(
+ array(
+ 'target' => $this->list->title->getPrefixedText(),
+ 'file' => $file->getArchiveName(),
+ 'token' => $user->getEditToken( $file->getArchiveName() )
+ ),
+ false, PROTO_RELATIVE
+ ),
+ );
+ }
+ if ( $file->userCan( Revision::DELETED_USER, $user ) ) {
+ $ret += array(
+ 'userid' => $file->user,
+ 'user' => $file->user_text,
+ );
+ }
+ if ( $file->userCan( Revision::DELETED_COMMENT, $user ) ) {
+ $ret += array(
+ 'comment' => $file->description,
+ );
+ }
+ return $ret;
+ }
}
/**
return "<li>$loglink $date $action $comment</li>";
}
+
+ public function getApiData( ApiResult $result ) {
+ $logEntry = DatabaseLogEntry::newFromRow( $this->row );
+ $user = $this->list->getUser();
+ $ret = array(
+ 'id' => $logEntry->getId(),
+ 'type' => $logEntry->getType(),
+ 'action' => $logEntry->getSubtype(),
+ );
+ $ret += $logEntry->isDeleted( LogPage::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+ $ret += $logEntry->isDeleted( LogPage::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+ $ret += $logEntry->isDeleted( LogPage::DELETED_ACTION ) ? array( 'actionhidden' => '' ) : array();
+
+ if ( LogEventsList::userCan( $this->row, LogPage::DELETED_ACTION, $user ) ) {
+ ApiQueryLogEvents::addLogParams(
+ $result,
+ $ret,
+ $logEntry->getParameters(),
+ $logEntry->getType(),
+ $logEntry->getSubtype(),
+ $logEntry->getTimestamp(),
+ $logEntry->isLegacy()
+ );
+ }
+ if ( LogEventsList::userCan( $this->row, LogPage::DELETED_USER, $user ) ) {
+ $ret += array(
+ 'userid' => $this->row->log_user,
+ 'user' => $this->row->log_user_text,
+ );
+ }
+ if ( LogEventsList::userCan( $this->row, LogPage::DELETED_COMMENT, $user ) ) {
+ $ret += array(
+ 'comment' => $this->row->log_comment,
+ );
+ }
+ return $ret;
+ }
}
* transactions are done here.
*
* @param array $params Associative array of parameters. Members are:
- * value: The integer value to set the visibility to
- * comment: The log comment.
+ * value: The integer value to set the visibility to
+ * comment: The log comment.
+ * perItemStatus: Set if you want per-item status reports
* @return Status
+ * @since 1.23 Added 'perItemStatus' param
*/
public function setVisibility( $params ) {
$bitPars = $params['value'];
$comment = $params['comment'];
+ $perItemStatus = isset( $params['perItemStatus'] ) ? $params['perItemStatus'] : false;
$this->res = false;
$dbw = wfGetDB( DB_MASTER );
$idsForLog = array();
$authorIds = $authorIPs = array();
+ if ( $perItemStatus ) {
+ $status->itemStatuses = array();
+ }
+
for ( $this->reset(); $this->current(); $this->next() ) {
$item = $this->current();
unset( $missing[$item->getId()] );
+ if ( $perItemStatus ) {
+ $itemStatus = Status::newGood();
+ $status->itemStatuses[$item->getId()] = $itemStatus;
+ } else {
+ $itemStatus = $status;
+ }
+
$oldBits = $item->getBits();
// Build the actual new rev_deleted bitfield
$newBits = RevisionDeleter::extractBitfield( $bitPars, $oldBits );
if ( $oldBits == $newBits ) {
- $status->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
+ $itemStatus->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
$status->failCount++;
continue;
} elseif ( $oldBits == 0 && $newBits != 0 ) {
if ( $item->isHideCurrentOp( $newBits ) ) {
// Cannot hide current version text
- $status->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
+ $itemStatus->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
$status->failCount++;
continue;
}
// Cannot access this revision
$msg = ( $opType == 'show' ) ?
'revdelete-show-no-access' : 'revdelete-modify-no-access';
- $status->error( $msg, $item->formatDate(), $item->formatTime() );
+ $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
$status->failCount++;
continue;
}
// Cannot just "hide from Sysops" without hiding any fields
if ( $newBits == Revision::DELETED_RESTRICTED ) {
- $status->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
+ $itemStatus->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
$status->failCount++;
continue;
}
$authorIPs[] = $item->getAuthorName();
}
} else {
- $status->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
+ $itemStatus->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
$status->failCount++;
}
}
// Handle missing revisions
foreach ( $missing as $id => $unused ) {
- $status->error( 'revdelete-modify-missing', $id );
+ if ( $perItemStatus ) {
+ $status->itemStatuses[$id] = Status::newFatal( 'revdelete-modify-missing', $id );
+ } else {
+ $status->error( 'revdelete-modify-missing', $id );
+ }
$status->failCount++;
}
if ( $status->successCount == 0 ) {
- $status->ok = false;
$dbw->rollback( __METHOD__ );
return $status;
}
* @return boolean success
*/
abstract public function setBits( $newBits );
+
+ /**
+ * Get the return information about the revision for the API
+ * @since 1.23
+ * @param ApiResult $result API result object
+ * @return array Data for the API result
+ */
+ abstract public function getApiData( ApiResult $result );
}
$this->namespaces = null;
$parsed = substr( $query, strlen( $allkeyword ) );
} elseif ( strpos( $query, ':' ) !== false ) {
- $prefix = substr( $query, 0, strpos( $query, ':' ) );
+ $prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
$index = $wgContLang->getNsIndex( $prefix );
if ( $index !== false ) {
$this->namespaces = array( $index );
function free() {
// ...
}
+
+ /**
+ * Did the search contain search syntax? If so, Special:Search won't offer
+ * the user a link to a create a page named by the search string because the
+ * name would contain the search syntax.
+ */
+ public function searchContainedSyntax() {
+ return false;
+ }
}
/**
global $wgSpecialPages;
global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
global $wgEnableEmail, $wgEnableJavaScriptTest;
- global $wgMiserMode;
if ( !is_object( self::$list ) ) {
wfProfileIn( __METHOD__ );
self::$list['JavaScriptTest'] = 'SpecialJavaScriptTest';
}
- if ( !$wgMiserMode ) {
- self::$list['Activeusers'] = 'SpecialActiveUsers';
- }
+ self::$list['Activeusers'] = 'SpecialActiveUsers';
// Add extension special pages
self::$list = array_merge( self::$list, $wgSpecialPages );
}
function getIndexField() {
- return 'rc_user_text';
+ return 'qcc_title';
}
function getQueryInfo() {
$dbr = $this->getDatabase();
- $conds = array( 'rc_user > 0' ); // Users - no anons
- $conds[] = 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' );
- $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes(
- $dbr->timestamp( wfTimestamp( TS_UNIX ) - $this->RCMaxAge * 24 * 3600 ) );
-
+ $conds = array(
+ 'qcc_type' => 'activeusers',
+ 'qcc_namespace' => NS_USER,
+ 'user_name = qcc_title',
+ 'rc_user_text = qcc_title'
+ );
if ( $this->requestedUser != '' ) {
- $conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser );
+ $conds[] = 'qcc_title >= ' . $dbr->addQuotes( $this->requestedUser );
}
-
if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
$conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
- 'ipblocks', '1', array( 'rc_user=ipb_user', 'ipb_deleted' => 1 )
+ 'ipblocks', '1', array( 'ipb_user=user_id', 'ipb_deleted' => 1 )
) . ')';
}
return array(
- 'tables' => array( 'recentchanges' ),
- 'fields' => array(
- 'user_name' => 'rc_user_text', // for Pager inheritance
- 'rc_user_text', // for Pager
- 'user_id' => 'MAX(rc_user)', // Postgres
- 'recentedits' => 'COUNT(*)'
- ),
- 'options' => array(
- 'GROUP BY' => array( 'rc_user_text' ),
- 'USE INDEX' => array( 'recentchanges' => 'rc_user_text' )
- ),
+ 'tables' => array( 'querycachetwo', 'user', 'recentchanges' ),
+ 'fields' => array( 'user_name', 'user_id', 'recentedits' => 'COUNT(*)', 'qcc_title' ),
+ 'options' => array( 'GROUP BY' => array( 'qcc_title' ) ),
'conds' => $conds
);
}
$out->wrapWikiMsg( "<div class='mw-activeusers-intro'>\n$1\n</div>",
array( 'activeusers-intro', $this->getLanguage()->formatNum( $wgActiveUserDays ) ) );
+ // Occasionally merge in new updates
+ $seconds = self::mergeActiveUsers( 600 );
+ // Mention the level of staleness
+ $out->addWikiMsg( 'cachedspecial-viewing-cached-ttl',
+ $this->getLanguage()->formatDuration( $seconds ) );
+
$up = new ActiveUsersPager( $this->getContext(), null, $par );
# getBody() first to check, if empty
protected function getGroupName() {
return 'users';
}
+
+ /**
+ * @param integer $period Seconds (do updates no more often than this)
+ * @return integer How many seconds old the cache is
+ */
+ public static function mergeActiveUsers( $period ) {
+ global $wgActiveUserDays;
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $cTime = $dbr->selectField( 'querycache_info',
+ 'qci_timestamp',
+ array( 'qci_type' => 'activeusers' )
+ );
+ if ( !wfReadOnly() ) {
+ if ( !$cTime || ( time() - wfTimestamp( TS_UNIX, $cTime ) ) > $period ) {
+ $dbw = wfGetDB( DB_MASTER );
+ self::doQueryCacheUpdate( $dbw, 2 * $period );
+ }
+ }
+ return ( time() -
+ ( $cTime ? wfTimestamp( TS_UNIX, $cTime ) : $wgActiveUserDays * 86400 ) );
+ }
+
+ /**
+ * @param DatabaseBase $dbw Passed in from updateSpecialPages.php
+ * @return void
+ */
+ public static function cacheUpdate( DatabaseBase $dbw ) {
+ global $wgActiveUserDays;
+
+ self::doQueryCacheUpdate( $dbw, $wgActiveUserDays * 86400 );
+ }
+
+ /**
+ * Update the query cache as needed
+ *
+ * @param DatabaseBase $dbw
+ * @param integer $window Maximum time range of new data to scan (in seconds)
+ * @return bool Success
+ */
+ protected static function doQueryCacheUpdate( DatabaseBase $dbw, $window ) {
+ global $wgActiveUserDays;
+
+ $lockKey = wfWikiID() . '-activeusers';
+ if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
+ return false; // exclusive update (avoids duplicate entries)
+ }
+
+ $now = time();
+ $cTime = $dbw->selectField( 'querycache_info',
+ 'qci_timestamp',
+ array( 'qci_type' => 'activeusers' )
+ );
+ $cTimeUnix = $cTime ? wfTimestamp( TS_UNIX, $cTime ) : 1;
+
+ // Pick the date range to fetch from. This is normally from the last
+ // update to till the present time, but has a limited window for sanity.
+ // If the window is limited, multiple runs are need to fully populate it.
+ $sTimestamp = max( $cTimeUnix, $now - $wgActiveUserDays * 86400 );
+ $eTimestamp = min( $sTimestamp + $window, $now );
+
+ // Get all the users active since the last update
+ $res = $dbw->select(
+ array( 'recentchanges' ),
+ array( 'rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)' ),
+ array(
+ 'rc_user > 0', // actual accounts
+ 'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes( 'newusers' ),
+ 'rc_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $sTimestamp ) ),
+ 'rc_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $eTimestamp ) )
+ ),
+ __METHOD__,
+ array(
+ 'GROUP BY' => array( 'rc_user_text' ),
+ 'ORDER BY' => 'NULL' // avoid filesort
+ )
+ );
+ $names = array();
+ foreach ( $res as $row ) {
+ $names[$row->rc_user_text] = $row->lastedittime;
+ }
+
+ // Rotate out users that have not edited in too long (according to old data set)
+ $dbw->delete( 'querycachetwo',
+ array(
+ 'qcc_type' => 'activeusers',
+ 'qcc_value < ' . $dbw->addQuotes( $now - $wgActiveUserDays * 86400 ) // TS_UNIX
+ ),
+ __METHOD__
+ );
+
+ // Find which of the recently active users are already accounted for
+ if ( count( $names ) ) {
+ $res = $dbw->select( 'querycachetwo',
+ array( 'user_name' => 'qcc_title' ),
+ array(
+ 'qcc_type' => 'activeusers',
+ 'qcc_namespace' => NS_USER,
+ 'qcc_title' => array_keys( $names ) ),
+ __METHOD__
+ );
+ foreach ( $res as $row ) {
+ unset( $names[$row->user_name] );
+ }
+ }
+
+ // Insert the users that need to be added to the list (which their last edit time
+ if ( count( $names ) ) {
+ $newRows = array();
+ foreach ( $names as $name => $lastEditTime ) {
+ $newRows[] = array(
+ 'qcc_type' => 'activeusers',
+ 'qcc_namespace' => NS_USER,
+ 'qcc_title' => $name,
+ 'qcc_value' => wfTimestamp( TS_UNIX, $lastEditTime ),
+ 'qcc_namespacetwo' => 0, // unused
+ 'qcc_titletwo' => '' // unused
+ );
+ }
+ foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
+ $dbw->insert( 'querycachetwo', $rowBatch, __METHOD__ );
+ wfWaitForSlaves();
+ }
+ }
+
+ // Touch the data freshness timestamp
+ $dbw->replace( 'querycache_info',
+ array( 'qci_type' ),
+ array( 'qci_type' => 'activeusers',
+ 'qci_timestamp' => $dbw->timestamp( $eTimestamp ) ), // not always $now
+ __METHOD__
+ );
+
+ $dbw->unlock( $lockKey, __METHOD__ );
+
+ return true;
+ }
}
$out = $this->getOutput();
- $out->addModules( 'mediawiki.tests.qunit.testrunner' );
+ $out->addModules( 'test.mediawiki.qunit.testrunner' );
$qunitTestModules = $out->getResourceLoader()->getTestModuleNames( 'qunit' );
$out->addModules( $qunitTestModules );
$title = $this->msg( 'passwordreset-emailtitle' );
- $this->result = $firstUser->sendMail( $title->escaped(), $this->email->text() );
+ $this->result = $firstUser->sendMail( $title->text(), $this->email->text() );
if ( isset( $data['Capture'] ) && $data['Capture'] ) {
// Save the user, will be used if an error occurs when sending the email
public function getFeedQuery() {
global $wgFeedLimit;
- $this->getOptions()->validateIntBounds( 'limit', 0, $wgFeedLimit );
$options = $this->getOptions()->getChangedValues();
// wfArrayToCgi() omits options set to null or false
}
unset( $value );
+ if ( isset( $options['limit'] ) && $options['limit'] > $wgFeedLimit ) {
+ $options['limit'] = $wgFeedLimit;
+ }
+
return wfArrayToCgi( $options );
}
if ( !is_null( $t ) ) {
global $wgGoToEdit;
wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) );
- wfDebugLog( 'nogomatch', $t->getText(), false );
+ wfDebugLog( 'nogomatch', $t->getText(), 'private' );
# If the feature is enabled, go straight to the edit page
if ( $wgGoToEdit ) {
// prev/next links
if ( $num || $this->offset ) {
// Show the create link ahead
- $this->showCreateLink( $t, $num );
+ $this->showCreateLink( $t, $num, $titleMatches, $textMatches );
$prevnext = $this->getLanguage()->viewPrevNext( $this->getPageTitle(), $this->offset, $this->limit,
$this->powerSearchOptions() + array( 'search' => $term ),
max( $titleMatchesNum, $textMatchesNum ) < $this->limit
} else {
$out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>",
array( 'search-nonefound', wfEscapeWikiText( $term ) ) );
- $this->showCreateLink( $t, $num );
+ $this->showCreateLink( $t, $num, $titleMatches, $textMatches );
}
}
$out->addHtml( "</div>" );
/**
* @param $t Title
* @param int $num The number of search results found
+ * @param $titleMatches null|SearchResultSet results from title search
+ * @param $textMatches null|SearchResultSet results from text search
*/
- protected function showCreateLink( $t, $num ) {
+ protected function showCreateLink( $t, $num, $titleMatches, $textMatches ) {
// show direct page/create link if applicable
// Check DBkey !== '' in case of fragment link only.
- if ( is_null( $t ) || $t->getDBkey() === '' ) {
+ if ( is_null( $t ) || $t->getDBkey() === '' ||
+ ( $titleMatches !== null && $titleMatches->searchContainedSyntax() ) ||
+ ( $textMatches !== null && $textMatches->searchContainedSyntax() ) ) {
// invalid title
// preserve the paragraph for margins etc...
$this->getOutput()->addHtml( '<p></p>' );
if ( !$status->isOk() ) {
return $status;
}
- wfDebugLog( 'fileconcatenate', "Combined $i chunks in $tAmount seconds.\n" );
+ wfDebugLog( 'fileconcatenate', "Combined $i chunks in $tAmount seconds." );
// File system path
$this->mTempPath = $tmpPath;
$this->mLocalFile = parent::stashFile( $this->user );
$tAmount = microtime( true ) - $tStart;
$this->mLocalFile->setLocalReference( $tmpFile ); // reuse (e.g. for getImageInfo())
- wfDebugLog( 'fileconcatenate', "Stashed combined file ($i chunks) in $tAmount seconds.\n" );
+ wfDebugLog( 'fileconcatenate', "Stashed combined file ($i chunks) in $tAmount seconds." );
return $status;
}
'undelete_short' => 'استرجاع {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}',
'viewdeleted_short' => 'استعرض {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}',
'protect' => 'حماية',
-'protect_change' => 'غيّر',
+'protect_change' => 'غير',
'protectthispage' => 'احم هذه الصفحة',
'unprotect' => 'غير الحماية',
'unprotectthispage' => 'غير حماية هذه الصفحة',
'recentchanges-feed-description' => 'تابع أحدث التغييرات للويكي عبر هذه التلقيمة.',
'recentchanges-label-newpage' => 'أنشأ هذا التعديل صفحة جديدة',
'recentchanges-label-minor' => 'هذا تعديل طفيف',
-'recentchanges-label-bot' => 'Ø£Ù\8fجÙ\92رÙ\90Ù\8aÙ\8e Ù\87ذا اÙ\84تعدÙ\8aÙ\84 بÙ\88اسطة بوت',
+'recentchanges-label-bot' => 'تعدÙ\8aÙ\84 أجراÙ\87 بوت',
'recentchanges-label-unpatrolled' => 'لم يراجع هذا التعديل إلى الآن',
'recentchanges-label-plusminus' => 'حجم الصفحة تغير بهذا العدد من وحدات البايت',
'recentchanges-legend-heading' => 'شرح',
'passwordreset-username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
'passwordreset-domain' => 'ܪܘܚܬܐ:',
'passwordreset-email' => 'ܡܘܢܥܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
+'passwordreset-emailsent' => 'ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ ܐܫܬܕܪ ܠܣܘܝܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
# Special:ChangeEmail
'changeemail' => 'ܫܚܠܦ ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ',
'content-failed-to-parse' => 'Fallu al analizar el conteníu $2 pal modelu $1: $3',
'invalid-content-data' => 'Datos del conteníu inválidos',
'content-not-allowed-here' => 'El conteníu «$1» nun se permite na páxina [[$2]]',
-'editwarning-warning' => 'Salir d\'esta páxina pue causar la perda de cualesquier cambiu fechu.
-Si aniciasti sesión, pue desactivase esti avisu na seición "Edición" de les tos preferencies.',
+'editwarning-warning' => "Salir d'esta páxina pue causar la perda de cualesquier cambiu fechu.
+Si anició sesión, pue desactivar esti avisu na seición «{{int:prefs-editing}}» de les preferencies.",
'editpage-notsupportedcontentformat-title' => 'El formatu del conteníu nun tien sofitu',
'editpage-notsupportedcontentformat-text' => 'El formatu del conteníu, $1, nun tien sofitu del modelu de conteníu $2.',
'showhideselectedversions' => 'Amosar/anubrir les versiones seleicionaes',
'editundo' => 'desfacer',
'diff-empty' => '(Nun hai diferencies)',
+'diff-multi-sameuser' => "({{PLURAL:$1|Nun s'amuesa una revisión intermedia|Nun s'amuesen $1 revisiones intermedies}} del mesmu usuariu)",
+'diff-multi-otherusers' => "(Nun s'{{PLURAL:$1|amuesa una revisión intermedia|amuesen $1 revisiones intermedies}} {{PLURAL:$2|d'otru usuariu|de $2 usuarios}})",
'diff-multi-manyusers' => "({{PLURAL:$1|Nun s'amuesa una revisión intermedia|Nun s'amuesen $1 revisiones intermedies}} de más de $2 {{PLURAL:$2|usuariu|usuarios}})",
'difference-missing-revision' => "{{PLURAL:$2|Nun s'alcontró|Nun s'alcontraron}} {{PLURAL:$2|una revisión|$2 revisiones}} d'esta diferencia ($1).
'shown-title' => 'Amosar $1 {{PLURAL:$1|resultáu|resultaos}} por páxina',
'viewprevnext' => 'Ver ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''Hai una páxina nomada \"[[\$1]]\" nesta wiki'''",
-'searchmenu-new' => "'''¡Crear la páxina \"[[:\$1]]\" nesta wiki!'''",
+'searchmenu-new' => "<strong>¡Crear la páxina «[[:$1]]» nesta wiki!</strong> {{PLURAL:$2|0=|Vea tamién la páxina que s'alcontró cola gueta.|Vea tamién los resultaos qu'alcontró la gueta.}}",
'searchprofile-articles' => 'Páxines de conteníu',
'searchprofile-project' => 'Páxines de proyeutu y ayuda',
'searchprofile-images' => 'Multimedia',
'invalid-content-data' => 'Няслушныя зьвесткі',
'content-not-allowed-here' => 'Зьмест тыпу «$1» на старонцы [[$2]] не дазволены',
'editwarning-warning' => 'Пакінуўшы гэтую старонку, вы можаце страціць усе ўнесеныя зьмены.
-Калі вы ўвайшлі ў сыстэму, Вы можаце адключыць гэтае папярэджаньне ў сэкцыі «Рэдагаваньне» вашых наладаў.',
+Калі вы ўвайшлі ў сыстэму, Вы можаце адключыць гэтае папярэджаньне ў сэкцыі «{{int:prefs-editing}}» вашых наладаў.',
'editpage-notsupportedcontentformat-title' => 'Фармат зьмесьціва не падтрымліваецца',
'editpage-notsupportedcontentformat-text' => 'Фармат зьмесьціва $1 не падтрымліваецца мадэльлю зьмесьціва $2.',
'undo-success' => 'Рэдагаваньне можа быць адмененае. Калі ласка, параўнайце адрозьненьні паміж вэрсіямі, каб упэўніцца, што гэта адпаведныя зьмены, а потым запішыце зьмены для сканчэньня рэдагаваньня.',
'undo-failure' => 'Рэдагаваньне ня можа быць скасаванае праз канфлікт паміж папярэднімі рэдагаваньнямі.',
'undo-norev' => 'Рэдагаваньне ня можа быць адмененае, таму што яно не існуе альбо было выдаленае.',
+'undo-nochange' => 'Выглядае, што праўка ўжо была адмененая.',
'undo-summary' => 'Скасаваньне праўкі $1 {{GENDER:$2|удзельніка|удзельніцы}} [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])',
'undo-summary-username-hidden' => 'Вэрсія $1 скасаваная схаваным удзельнікам',
'editundo' => 'скасаваць',
'diff-empty' => '(Розьніцы няма)',
'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|не паказаная|не паказаныя|не паказаныя}})',
'difference-missing-revision' => '{{PLURAL:$2|$2 вэрсія|$2 вэрсіі|$2 вэрсіяў}} з гэтымі адрозьненьнямі ($1) {{PLURAL:$2|не была|не былі}} знойдзеныя.
Калі Вы жадаеце загрузіць Ваш файл, вярніцеся назад і загрузіце гэты файл з новай назвай. [[File:$1|thumb|center|$1]]',
'file-exists-duplicate' => 'Гэты файл дублюе {{PLURAL:$1|1=наступны файл|наступныя файлы}}:',
'file-deleted-duplicate' => 'Падобны файл ([[:$1]]) ужо выдаляўся. Калі ласка, паглядзіце гісторыю выдаленьняў гэтага файла перад яго паўторнай загрузкай.',
+'file-deleted-duplicate-notitle' => 'Файл, ідэнтычны гэтаму файлу, раней ужо быў выдалены, а назва файла была забароненая.
+Вам трэба зьвярнуцца да некага з правамі прагляду зьвестак забароненых файлаў, каб прааналізаваць сытуацыю перад тым, як загружаць файл ізноў.',
'uploadwarning' => 'Папярэджаньне',
'uploadwarning-text' => 'Калі ласка, зьмяніце апісаньне файла ніжэй і паспрабуйце ізноў.',
'savefile' => 'Захаваць файл',
# Special:Categories
'categories' => 'Катэгорыі',
-'categoriespagetext' => '{{PLURAL:$1|1=Наступная катэгорыя зьмяшчае|Наступныя катэгорыі зьмяшчаюць}} старонкі і/альбо мэдыяфайлы.
+'categoriespagetext' => '{{PLURAL:$1|1=Наступная катэгорыя зьмяшчае|Наступныя катэгорыі зьмяшчаюць}} старонкі альбо мэдыяфайлы.
Тут не паказаныя [[Special:UnusedCategories|катэгорыі, якія не выкарыстоўваюцца]].
Глядзіце таксама [[Special:WantedCategories|сьпіс запатрабаваных катэгорыяў]].',
'categoriesfrom' => 'Паказаць катэгорыі, пачынаючы з:',
'linksearch-pat' => 'Узор для пошуку:',
'linksearch-ns' => 'Прастора назваў:',
'linksearch-ok' => 'Шукаць',
-'linksearch-text' => 'Можна ўжываць сымбалі падстаноўкі, напрыклад, «*.wikipedia.org».<br />
+'linksearch-text' => 'Можна ўжываць сымбалі падстаноўкі, напрыклад, «*.wikipedia.org».
Неабходны дамэн першага ўзроўню, напрыклад, «*.org».<br />
{{PLURAL:$2|1=Пратакол, які падтрымліваецца|Пратаколы, якія падтрымліваюцца}}: <code>$1</code> (дапомна http://, калі пратакол не пазначаны).',
'linksearch-line' => 'Спасылка на $1 з $2',
'listgrouprights-rights' => 'Правы',
'listgrouprights-helppage' => 'Help:Правы групаў удзельнікаў',
'listgrouprights-members' => '(сьпіс удзельнікаў групы)',
-'listgrouprights-addgroup' => 'можа дадаваць {{PLURAL:$2|1=групу|групы}}: $1',
-'listgrouprights-removegroup' => 'можа выдаляць {{PLURAL:$2|1=групу|групы}}: $1',
+'listgrouprights-addgroup' => 'можа дадаваць у {{PLURAL:$2|1=групу|групы}}: $1',
+'listgrouprights-removegroup' => 'можа выдаляць з {{PLURAL:$2|1=групы|групаў}}: $1',
'listgrouprights-addgroup-all' => 'можа дадаваць усе групы',
'listgrouprights-removegroup-all' => 'можа выдаляць усе групы',
-'listgrouprights-addgroup-self' => 'Ð\9cожа дадаць уласны рахунак да {{PLURAL:$2|1=групы|групаў}}: $1',
-'listgrouprights-removegroup-self' => 'Ð\9cожа выдаліць уласны рахунак з {{PLURAL:$2|1=групы|групаў}}: $1',
+'listgrouprights-addgroup-self' => 'можа дадаць уласны рахунак да {{PLURAL:$2|1=групы|групаў}}: $1',
+'listgrouprights-removegroup-self' => 'можа выдаліць уласны рахунак з {{PLURAL:$2|1=групы|групаў}}: $1',
'listgrouprights-addgroup-self-all' => 'Можа дадаць уласны рахунак да ўсіх груп',
'listgrouprights-removegroup-self-all' => 'Можа выдаліць уласны рахунак з ўсіх груп',
'shown-title' => 'প্রতি পাতায় $1 {{PLURAL:$1|ফলাফল|ফলাফলসমূহ}} দেখাও',
'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) দেখানো হোক।',
'searchmenu-exists' => "'''এই উইকিতে \"[[:\$1]]\" নামে একটি পাতা রয়েছে'''",
-'searchmenu-new' => "'''\"[[:\$1]]\" পাতাটি এই উইকিতে তৈরি করুন!'''",
+'searchmenu-new' => '<strong>"[[:$1]]" পাতাটি এই উইকিতে তৈরি করুন!</strong> {{PLURAL:$2|0=|এছাড়া আপনার অনুসন্ধানের সাথে পাওয়া পাতা দেখুন।|এছাড়া অনুসন্ধানে পাওয়া ফলাফলগুলি দেখুন।}}',
'searchprofile-articles' => 'বিষয়বস্তুর পাতা',
'searchprofile-project' => 'সহায়িকা এবং প্রকল্প পাতা',
'searchprofile-images' => 'মাল্টিমিডিয়া',
'delete-warning-toobig' => 'এই পাতাটির একটি বৃহৎ সম্পাদনা ইতিহাস রয়েছে, যা $1 {{PLURAL:$1|সংস্করণেরও|সংস্করণেরও}} বেশি।
এই পাতাটি মুছে ফেললে তা {{SITENAME}} সাইটের ডেটাবেজ সমস্যার কারণ হতে পারে;
সাবধানতার সাথে এগিয়ে যান।',
-'deleting-backlinks-warning' => "'''সতর্কীকরণ:''' আপনি যেটি মুছে ফেলতে যাচ্ছেন তা অন্যান্য পাতাসমূহের সাথে সংযুক্ত আছে।",
+'deleting-backlinks-warning' => "'''সতরà§\8dà¦\95à§\80à¦\95রণ:''' à¦\86পনি যà§\87à¦\9fি মà§\81à¦\9bà§\87 ফà§\87লতà§\87 যাà¦\9aà§\8dà¦\9bà§\87ন তা à¦\85নà§\8dযানà§\8dয পাতাসমà§\82হà§\87র সাথà§\87 সà¦\82যà§\81à¦\95à§\8dত à¦\85থবা à¦\85নà§\8dতরà§\8dà¦à§\81à¦\95à§\8dত à¦\95রা à¦\86à¦\9bà§\87।",
# Rollback
'rollback' => 'সম্পাদনা ফিরিয়ে নিন',
'range_block_disabled' => 'প্রশাসকের পক্ষে আইপি ঠিকানার শ্রেণী বাধাদানের ক্ষমতা নিষ্ক্রিয় আছে।',
'ipb_expiry_invalid' => 'মেয়াদোত্তীর্ণকাল অবৈধ।',
'ipb_expiry_temp' => 'লুকানো ব্যবহারকারীনাম বাধা চিরস্থায়ী হতে হবে।',
-'ipb_hide_invalid' => 'à¦\8fà¦\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f বাধা দà§\87য়া সমà§\8dà¦à¦¬ নয়; হয়তà§\8b সমà§\8dপাদনার সà¦\82à¦\96à§\8dযা à¦\85নà§\87à¦\95 বà§\87শি।',
+'ipb_hide_invalid' => 'à¦\8fà¦\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f বাধা দà§\87য়া সমà§\8dà¦à¦¬ নয়; à¦\8fà¦\9fি {{PLURAL:$1|à¦\8fà¦\95à§\87র à¦\85ধিà¦\95|$1à¦\9fি}} সমà§\8dপাদনা à¦\95রà§\87à¦\9bà§\87।',
'ipb_already_blocked' => '"$1" ইতিমধ্যে ব্লক',
'ipb-needreblock' => '$1 পূর্বেই ব্লক রয়েছেন। আপনি কি সেটিংস পরিবর্তন করতে চান?',
'ipb-otherblocks-header' => 'অন্যান্য {{PLURAL:$1|বাধাঁ|বাধাঁসমূহ}}',
'version-ext-colheader-license' => 'লাইসেন্স',
'version-ext-colheader-description' => 'বিবরণ',
'version-ext-colheader-credits' => 'লেখক',
+'version-license-title' => '$1-এর জন্য লাইসেন্স',
+'version-credits-title' => '$1-এর জন্য কৃতিত্ব',
+'version-credits-not-found' => 'এই এক্সটেনশনটির জন্য কোনো বিস্তারিত কৃতিত্ব তথ্য পাওয়া যায়নি।',
'version-poweredby-credits' => "এইক উইকিটি পরিচালিত হচ্ছে '''[https://www.mediawiki.org/ মিডিয়াউইকি]'''-এর মাধ্যমে, কপিরাইট © ২০০১-$1 $2।",
'version-poweredby-others' => 'অন্যান্য',
'version-poweredby-translators' => 'translatewiki.net অনুবাদকগণ',
# Special:Redirect
'redirect' => 'পাতা, ফাইল, ব্যবহারকরী, অথবা সংশোধন আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে',
'redirect-legend' => 'একটি ফাইল অথবা পাতায় পুনঃনির্দেশ করা হয়েছে',
-'redirect-summary' => 'à¦\8fà¦\87 বিশà§\87ষ পাতাà¦\9fি পà§\81নà¦\83নিরà§\8dদà§\87শিত হয়à§\87à¦\9bà§\87 à¦\8fà¦\95à¦\9fি ফাà¦\87লà§\87 (ফাà¦\87লà§\87র নাম), à¦\8fà¦\95à¦\9fি পাতা (রিà¦à¦¿à¦¶à¦¨ à¦\86à¦\87ডি), à¦\85থবা à¦\8fà¦\95à¦\9fি বà§\8dযবহারà¦\95রà§\80 পাতায় (সà¦\82à¦\96à§\8dযায় লà§\87à¦\96া বà§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি)। বà§\8dযবহার: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]]।',
+'redirect-summary' => 'à¦\8fà¦\87 বিশà§\87ষ পাতাà¦\9fি à¦\8fà¦\95à¦\9fি ফাà¦\87লà§\87 (ফাà¦\87লà§\87র নাম), à¦\8fà¦\95à¦\9fি পাতায় (সà¦\82সà§\8dà¦\95রণ à¦\86à¦\87ডি বা পাতা à¦\86à¦\87ডি), à¦\85থবা à¦\8fà¦\95à¦\9fি বà§\8dযবহারà¦\95রà§\80 পাতায় (সà¦\82à¦\96à§\8dযায় লà§\87à¦\96া বà§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি) পà§\81নà¦\83নিরà§\8dদà§\87শিত হয়à§\87à¦\9bà§\87। বà§\8dযবহার: [[{{#Special:Redirect}}/file/à¦\89দাহরণ.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], à¦\85থবা [[{{#Special:Redirect}}/user/101]]।',
'redirect-submit' => 'যাও',
'redirect-lookup' => 'দেখুন:',
'redirect-value' => 'মান:',
'recentchanges-label-bot' => "Gant ur bot eo bet degaset ar c'hemm-mañ.",
'recentchanges-label-unpatrolled' => "N'eo ket bet gwiriet ar c'hemm-mañ evit c'hoazh.",
'recentchanges-label-plusminus' => 'Kemmet eo ment ar bajenn eus an niver-mañ a oktedoù',
-'recentchanges-legend-heading' => '"Alc\'hwez :"',
+'recentchanges-legend-heading' => "'''Alc'hwez :'''",
'recentchanges-legend-newpage' => '(gwelet ivez [[Special:NewPages|roll ar pajennoù nevez]])',
'rcnotefrom' => "Setu aze roll ar c'hemmoù c'hoarvezet abaoe an '''$2''' ('''$1''' d'ar muiañ).",
'rclistfrom' => "Diskouez ar c'hemmoù diwezhañ abaoe an $1.",
'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwikis}}',
'nlinks' => '$1 {{PLURAL:$1|enllaç|enllaços}}',
'nmembers' => '$1 {{PLURAL:$1|membre|membres}}',
-'nmemberschanged' => '$1 → $2 {{PLURAL:$2|membre|membres}}',
+'nmemberschanged' => '$1 → $2 {{PLURAL:$2|element|elements}}',
'nrevisions' => '$1 {{PLURAL:$1|revisió|revisions}}',
'nviews' => '$1 {{PLURAL:$1|visita|visites}}',
'nimagelinks' => "S'utilitza en {{PLURAL:$1|una pàgina|$1 pàgines}}",
# Vector skin
'vector-action-addsection' => 'ТӀетоха хьедар',
'vector-action-delete' => 'ДӀаяккха',
-'vector-action-move' => 'Цlе хийца',
+'vector-action-move' => 'ЦӀе хийца',
'vector-action-protect' => 'Гlаролла дé',
'vector-action-undelete' => 'Меттахlоттадé',
'vector-action-unprotect' => 'ГӀароллех къаста',
ХӀу бахьна ду билгал дина дац.',
'no-null-revision' => '«$1» агӀона нисдар дан цаделира',
'badtitle' => 'Цамегаш йолу цlе',
-'badtitletext' => 'Дехарца йолу агlонан цlе нийса яц, йаьсса ю, хила мега нийса ца хlоттийна меттаюкъар йа юкъарвики цlе. Хила мега, цlарца цамагош йолу саберг.',
+'badtitletext' => 'Дехарца йолу агӀонан цӀе нийса яц, йаьсса ю, хила мега нийса ца хӀоттийна меттаюкъар йа юкъарвики цӀе. Хила мега, цӀарца цамагош йолу символаш.',
'perfcached' => 'Лахара хаам схьаэца кэша чура цундела тӀехьарлаьра хийцамаш гойтуш бац. Кэша чохь латтаё оцул $1 кӀезиг {{PLURAL:$1|1=дӀаяздар|дӀаяздарш}}.',
'perfcachedts' => 'Лахара хаам схьаэца кэша чура иза тӀаьхьара карла ялла $1. Кэша чохь латта до оцул $4 кӀезиг {{PLURAL:$4|1=дӀаяздар|дӀаяздарш}}.',
'querypage-no-updates' => 'ХӀинца хӀара агӀо карлаякхар дӀадайина ду.
'revdelete-hide-image' => 'Къайлабаккха файлан чулацам',
'revdelete-hide-name' => 'Къайлаяккха дешдерг а цуна объект а',
'revdelete-hide-comment' => 'Хийцамах лаьцнарг',
-'revdelete-hide-user' => 'Ð\9aÑ\8aайлаÑ\8fккÑ\85а авÑ\82оÑ\80ан Ñ\86Ó\80е',
+'revdelete-hide-user' => 'Ð\94екÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ñ\86Ó\80е/IP-адÑ\80еÑ\81',
'revdelete-radio-same' => '(ма хийца)',
'revdelete-radio-set' => 'Къайлаяьккхина',
'revdelete-radio-unset' => 'Гуш ерг',
# Diffs
'history-title' => '$1 — хийцаман истори',
'difference-title' => '$1 — Версешан башхалла',
-'lineno' => 'Могlа $1:',
+'lineno' => 'МогӀа $1:',
'compareselectedversions' => 'Хаьржина версеш муха ю хьажа',
'showhideselectedversions' => 'Гайта/къайлаяха хаьржина башхонаш',
'editundo' => 'цаоьшу',
'diff-empty' => '(башхалла яц)',
+'diff-multi-sameuser' => '(ца {{PLURAL:$1|гайтина юккъера цхьа верси|гайтина юккъера цхьа версеш}} оьцу декъашхочун)',
+'diff-multi-otherusers' => '(ца {{PLURAL:$1|гайтина юккъера верси|гайтина юккъера версеш}} {{PLURAL:$2|кхин цхьан декъашхочун|$2 декъашхойн}})',
# Search results
'searchresults' => 'Лахарна хилам',
'rc_categories_any' => 'Муьлхаа',
'rc-change-size-new' => 'Хийцам бинчул тӀехьа болу барам: $1 {{PLURAL:$1|байт}}',
'newsectionsummary' => '/* $1 */ Керла хьедар',
-'rc-enhanced-expand' => 'Гайта ма дарра дерг (лелош ю JavaScript)',
+'rc-enhanced-expand' => 'Гайта мадарра',
'rc-enhanced-hide' => 'Ма дарра дерг къайладаккха',
'rc-old-title' => 'дуьххьара кхоьллина яра цӀарца «$1»',
'doubleredirects' => 'Шалха дIасахьажийнарш',
'doubleredirectstext' => 'ХӀокху агӀонехь ю дӀасахьажорашан тӀе хьажийна йолу дӀасахьажораш.
<del>ТӀехула сиз хаькхна </del>нисйина чарна.',
-'double-redirect-fixed-move' => 'Агlон [[$1]] цlе хийцна, хlинца иза дlахьажийна оцу [[$2]]',
+'double-redirect-fixed-move' => 'АгӀон [[$1]] цӀе хийцина, хӀинца иза дӀахьажийна оцу [[$2]]',
'brokenredirects' => 'ДIахаьдна долу дIасахьажораш',
'brokenredirectstext' => 'Лахара дӀасахьажийнарш ю йоцучу агӀонийн тӀе хьажийна:',
'newpages' => 'Керла агlонаш',
'newpages-username' => 'Декъашхо:',
'ancientpages' => 'Яззамаш оцу терахьца тӀаьххьара тадар дина долу',
-'move' => 'Цlе хийца',
-'movethispage' => 'Хlокху агlон цlе хийца',
+'move' => 'ЦӀе хийца',
+'movethispage' => 'ХӀокху агӀон цӀе хийца',
'unusedimagestext' => 'Дехар до, тидаме эца, кхин йолу дуьнана машан-меттигаш а лелош хила мега нийсса йогӀу хьажораг (URL) хӀокху хӀуман, хӀокху могӀаме йогӀуш ялахь яцахь а иза хила мега жигара лелош.',
'unusedcategoriestext' => 'ХӀокху категорешан чохь агӀонаш я кхин категореш яц.',
'notargettitle' => 'Ӏалашо билгал йина яц',
'allinnamespace' => 'Массо агlонаш оцу цlери анахь «$1»',
'allpagessubmit' => 'Кхочушдé',
'allpagesprefix' => 'Лаха агlонаш, дlайуьлалуш йолу:',
-'allpagesbadtitle' => 'Цамагош йолу агlон цlе. Коьрта могlан юкъах ю юкъарвики меттанашан юкъе тlечlагlйина йолу хьаьрк йа магийна доцу оцу коьрта моlанца сабол элп йа кхин.',
+'allpagesbadtitle' => 'Цамагош йолу агӀон цӀе. Коьрта могӀан юкъах ю юкъарвики меттанашан юкъе тӀечӀагӀйина йолу хьаьрк йа магийна доцу оцу коьрта моӀанца символаш йа кхин.',
'allpages-bad-ns' => '{{SITENAME}} кху чохь ана цlераш яц «$1».',
'allpages-hide-redirects' => 'Къайлаяха дӀасахьажийнарш',
'notanarticle' => 'Бац яззам',
'watchlist-details' => 'Хьан тергаме могlамца $1 {{PLURAL:$1|агlо|агlонаш|агlонаш}} ю, дийцаре агlонаша йоцуш.',
'wlheader-showupdated' => "Хийцам бина агӀонаш '''Ӏаьржа''' шрифтцан билгальяха ю.",
+'wlnote2' => 'Лахахьа гайтина {{PLURAL:$1|тӀеххьара сахьт}} чохь бина хийцамаш $2 $3.',
'wlshowlast' => 'Гайта тlаьххьара $1 сахьташ $2 денош $3',
'watchlist-options' => 'Тергаме могlаман гlирс нисбар',
** авторан лаамца
** авторан бакъонаш талхор',
'delete-edit-reasonlist' => 'Бахьанин список нисяр',
+'deleting-backlinks-warning' => "'''ДӀахьедар.''' Ахьа дӀайоккхуш йолчун тӀе товжийна кхин агӀонаш ю.",
# Rollback
'rollback' => 'Юхабаккха хийцам',
'unprotectedarticle' => 'ГӀоролла дӀадаьстина «[[$1]]»',
'movedarticleprotection' => '«[[$2]]» агӀона тӀера гӀаролла «[[$1]]» агӀона тӀе даьккхина',
'protect-title' => 'Оцунна «$1» гӀоралла дар',
-'prot_1movedto2' => '«[[$1]]» цlе хийцина оцу «[[$2]]»',
+'prot_1movedto2' => '«[[$1]]» цӀе хийцина оцу «[[$2]]»',
'protect-legend' => 'Бакъде гӀоралла дар',
'protectcomment' => 'Бахьан:',
'protectexpiry' => 'Чекхйолу:',
'''ДӀАХЬЕДАР!'''
ЦӀе хийцар бахьнехь гӀаръялла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
-'movepagetalktext' => "Тlе хlоьттина йолу дийцаре агlо ишта цlе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''
+'movepagetalktext' => "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''
-*Йаьсса йоцу дийцаре агlо йолуш ю оцу цlарца йа
-*Ахьа къастаман харжам цабиняхь а къастам хlотточехь.
+*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа
+*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.
-Ишта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хlоттайар, нагахь иза хьашт йалахь.",
+Ишта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
'movearticle' => 'Цle хийца хlокху агlон',
'moveuserpage-warning' => "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
'newtitle' => 'Керла цlе',
'move-watch' => 'Латайé хӀара агӀо тергаме могӀанан юкъахь',
-'movepagebtn' => 'Агlон цlе хийца',
-'pagemovedsub' => 'Агlон цlе хийцина',
-'movepage-moved' => "'''Агlон цlе «$1» хийцина хlокху «$2»'''",
+'movepagebtn' => 'АгӀон цӀе хийца',
+'pagemovedsub' => 'АгӀон цӀе хийцина',
+'movepage-moved' => "'''АгӀон цӀе «$1» хийцина хӀокху «$2»'''",
'movepage-moved-redirect' => 'Кхоьллина дӀасахьажориг.',
'movepage-moved-noredirect' => 'ДӀасхьажориг кхоллар дохина.',
-'articleexists' => 'Хlарасанна цlе йолу агlо йолуш ю йа ахьа гойтуш йолу цlе магош яц.
-Дехар до, харжа кхин цlе.',
-'movetalk' => 'Цуьнца йогlуш йолу дийцаре агlон цlе хийцар',
+'articleexists' => 'ХӀарасанна цӀе йолу агӀо йолуш ю йа ахьа гойтуш йолу цӀе магош яц.
+Дехар до, харжа кхин цӀе.',
+'movetalk' => 'Цуьнца йогӀуш йолу дийцаре агӀон цӀе хийцар',
'move-subpages' => 'ЦӀeрш хийцае бухара агӀонаши ($1 кхаччалц)',
'move-talk-subpages' => 'ЦӀе хийца бухара агӀонаши а агӀонашан дийцаре а ($1 кхаччалц)',
'movepage-page-exists' => 'Агӏо $1 йолуш ю цундела и ша юху дӏаязъян йиш яц.',
'tooltip-ca-protect' => 'Гlаролла дé хlокху агlон хийцам цабайта',
'tooltip-ca-unprotect' => 'Дlадаккха хlокху агlонна долу гаролла',
'tooltip-ca-delete' => 'ДӀаяккха хӀара агӀо',
-'tooltip-ca-move' => 'Агlон цlе хийца',
+'tooltip-ca-move' => 'АгӀон цӀе хийца',
'tooltip-ca-watch' => 'ТӀетоха хӀара агӀо сан тергаме могӀанан юкъа',
'tooltip-ca-unwatch' => 'ДӀаяккха хӀара агӀо хьай тергаме могӀанан юкъар',
'tooltip-search' => 'Лаха иза дош',
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
'seconds-abbrev' => '$1оцу',
+'minutes-abbrev' => '$1 мин',
+'hours-abbrev' => '$1 сахь.',
'hours' => '{{PLURAL:$1|1 сахьт}}',
'days' => '{{PLURAL:$1|$1 де}}',
'weeks' => '{{PLURAL:$1|$1 кӀира}}',
'exif-bitspersample' => 'Бесан кIоргалла',
'exif-photometricinterpretation' => 'Беснин модель',
'exif-orientation' => 'Суьртан хьал',
+'exif-ycbcrpositioning' => 'Y а C а компонентин листаран кеп',
'exif-xresolution' => 'Шоралла',
'exif-yresolution' => 'Локхалла',
+'exif-referenceblackwhite' => 'Ӏаьржа а къай а тӀадамийн меттиг',
'exif-datetime' => 'Файл хийцина терахь а хан',
'exif-imagedescription' => 'Суьртан цӏе',
'exif-make' => 'Камера арахоьцург',
'exif-software' => 'Лелина программа',
'exif-copyright' => 'Авторан бакъо ерг',
'exif-exifversion' => 'Верси Exif',
+'exif-flashpixversion' => 'Ловш йолу верси FlashPix',
'exif-colorspace' => 'Беснашан хьал',
+'exif-componentsconfiguration' => 'Бесара компонентин конфигураци',
'exif-compressedbitsperpixel' => 'Бесан кIоргалла дацдина чул тӀехьа',
'exif-pixelxdimension' => 'Суьртан локхалла',
'exif-datetimeoriginal' => 'Дуьххьарлера терахь а хан',
'exif-datetimedigitized' => 'Оцифровк йина терахь а хан а',
-'exif-exposuretime' => 'Экспозицин хан',
+'exif-subsectime' => 'Файлан хийцам баран хан секундашкахь',
+'exif-exposuretime' => 'Сурт доккхуш йолу серлон хьал',
'exif-fnumber' => 'Диафрагмин дукхалла',
-'exif-maxaperturevalue' => 'Минимальни диафрагмин дукхалла',
+'exif-shutterspeedvalue' => 'APEX чура дешнаш',
+'exif-aperturevalue' => 'APEX чура оьз',
+'exif-exposurebiasvalue' => 'Сурт доккхуш яла оьшу серло меттаяло',
+'exif-maxaperturevalue' => 'Минимальни оьзан дукхалла',
+'exif-meteringmode' => 'Сурт доккхуш яла серло юьстаран хьал',
+'exif-flash' => 'Серлона статус',
'exif-focallength' => 'Фокусни бохалла',
+'exif-focalplanexresolution' => 'X магийна фокалан тӀапа',
+'exif-focalplaneyresolution' => 'Y магийна фокалан тӀапа',
+'exif-focalplaneresolutionunit' => 'Магоран фокалан дустар',
'exif-sensingmethod' => 'Сенсоран тайп',
'exif-filesource' => 'Файлан хьост',
+'exif-customrendered' => 'Кхин тӀе кечдар',
+'exif-exposuremode' => 'Сурт доккхуш йолу серлон хьал харжар',
+'exif-whitebalance' => 'Къайн баланс',
+'exif-digitalzoomratio' => 'Терхьаш дукха хиларан коэффициент',
+'exif-scenecapturetype' => 'Сурт доккхуш йолу меттиган тайп',
'exif-imageuniqueid' => 'Суьртан номер (ID)',
'exif-gpslatitude' => 'Шоралла',
'exif-gpslongitude' => 'Дохалла',
'exif-xyresolution-i' => '$1 тӏадамаш дюйман',
+'exif-meteringmode-5' => 'Матрин',
+
'exif-lightsource-1' => 'Ден хьехам',
+'exif-lightsource-4' => 'Серло',
'exif-lightsource-9' => 'Хаза хенан хӀоттам',
'exif-lightsource-10' => 'Мархаш йолу',
+'exif-focalplaneresolutionunit-2' => 'дюйм',
+
'exif-filesource-3' => 'Терахьийн суртдохку аппарат',
'exif-scenetype-1' => 'Сурт даьккхина нис дуьххьал',
+'exif-customrendered-0' => 'ХӀума дийна дац',
+'exif-customrendered-1' => 'Нийса доцу кечдар',
+
+'exif-whitebalance-0' => 'Къайн автоматически баланс',
+'exif-whitebalance-1' => 'Куьйга хӀоттийна къайн баланс',
+
+'exif-scenecapturetype-0' => 'Стандартан',
+
'exif-gaincontrol-0' => 'Яц',
'exif-contrast-0' => 'Лартӏахь',
'exif-sharpness-0' => 'Лартӏахь',
+'exif-ycbcrpositioning-1' => 'Юкъйина',
+
'exif-dc-date' => 'Терахь(ш)',
'exif-dc-rights' => 'Бакъонаш',
Шоьга кхача езаш яра [{{SERVER}}{{SCRIPTPATH}}/COPYING копи GNU General Public License] хӀокху программица, кхаьчна яцахь язъе Free Software Foundation, Inc., адрес тӀе: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA я [//www.gnu.org/licenses/old-licenses/gpl-2.0.html еша и онлайнехь].',
'version-software' => 'ДӀахӀоттийна программин латтор',
'version-software-version' => 'Верси',
+'version-entrypoints' => 'ЧугӀо адресин тӀадамаш',
# Special:Redirect
'redirect' => 'Декъашхочун файлан тӀера дӀасхьажор',
'logentry-newusers-newusers' => '{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1',
'logentry-newusers-create' => '{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1',
'logentry-newusers-autocreate' => 'Автоматически кхоьллина {{GENDER:$2|декъашхочун}} $1 дӀаяздар',
-'logentry-rights-rights' => '$1 {{GENDER:$2|хийцина}} хӀокхуна $3 бакъо $4 → $5',
+'logentry-rights-rights' => '$1 {{GENDER:$2|хийцина}} $3 бакъо $4 → $5',
'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|хийцина}} хӏокхуна $3 бакъо',
'rightsnone' => '(яц)',
* @author Littledogboy
* @author Martin Kozák
* @author Matěj Grabovský
+ * @author Matěj Suchánek
* @author Mercy
* @author Michawiki
* @author Mormegil
'invalid-content-data' => 'Obsažená data jsou chybná',
'content-not-allowed-here' => 'Obsah typu $1 není na stránce [[$2]] dovolen.',
'editwarning-warning' => 'Opuštěním této stránky se mohou veškeré provedené změny ztratit.
-Přihlášení uživatelé si mohou toto varování vypnout na záložce „Editace“ v uživatelském nastavení.',
+Přihlášení uživatelé si mohou toto varování vypnout na záložce „{{int:prefs-editing}}“ v uživatelském nastavení.',
'editpage-notsupportedcontentformat-title' => 'Nepodporovaný formát obsahu',
'editpage-notsupportedcontentformat-text' => 'Model obsahu $2 nepodporuje formát obsahu $1.',
'showhideselectedversions' => 'Zobrazit/skrýt vybrané revize',
'editundo' => 'zrušit editaci',
'diff-empty' => '(Žádný rozdíl)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Není zobrazena 1 mezilehlá verze|Nejsou zobrazeny $1 mezilehlé verze|Není zobrazeno $1 mezilehlých verzí}} od stejného uživatele.)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Není zobrazena 1 mezilehlá verze|Nejsou zobrazeny $1 mezilehlé verze|Není zobrazeno $1 mezilehlých verzí}} od {{PLURAL:$2|1 dalšího uživatele|$2 dalších uživatelů}}.)',
'diff-multi-manyusers' => '(Není zobrazeno $1 mezilehlých verzí od více než $2 {{PLURAL:$2|uživatele|uživatelů}}.)',
'difference-missing-revision' => '{{PLURAL:$2|Jedna z revizí|$2 revize|$2 revizí}} k požadovanému porovnání ($1) {{PLURAL:$2|neexistuje|neexistují|neexistuje}}.
'confirmdeletetext' => 'Chystáte se smazat stránku s celou její historií. Prosím potvrďte, že to opravdu chcete učinit, že si uvědomujete důsledky a že je to v souladu s [[{{MediaWiki:Policy-url}}|pravidly]].',
'actioncomplete' => 'Provedeno',
'actionfailed' => 'Operace se nezdařila',
-'deletedtext' => 'Stránka nebo soubor „$1“ byla smazána. $2 zaznamenává poslední smazání.',
+'deletedtext' => 'Stránka nebo soubor „$1“ byl(a) smazán(a). $2 zaznamenává poslední smazání.',
'dellogpage' => 'Kniha smazaných stránek',
'dellogpagetext' => 'Zde je seznam posledních smazaných stránek.',
'deletionlog' => 'Kniha smazaných stránek',
'delete-edit-reasonlist' => 'Editovat důvody smazání',
'delete-toobig' => 'Tato stránka má velkou historii editací, přes $1 {{PLURAL:$1|verzi|verze|verzí}}. Mazání takových stránek je omezeno, aby se předešlo nechtěnému narušení {{grammar:2sg|{{SITENAME}}}}.',
'delete-warning-toobig' => 'Tato stránka má velkou historii editací, přes $1 {{PLURAL:$1|verzi|verze|verzí}}. Mazání takových stránek může narušit databázové operace {{grammar:2sg|{{SITENAME}}}}; postupujte opatrně.',
-'deleting-backlinks-warning' => "'''Upozornění:''' Stránka, kterou se chystáte smazat, je na jiných stránkách odkazována nebo vkládána.",
+'deleting-backlinks-warning' => "'''Upozornění:''' Stránka, kterou se chystáte smazat, je na jiných stránkách odkazována nebo je do nich vložena.",
# Rollback
'rollback' => 'Vrátit zpět editace',
'cantrollback' => 'Nelze vrátit zpět poslední editaci, neboť poslední přispěvatel je jediným autorem této stránky.',
'alreadyrolled' => 'Nelze vrátit zpět poslední editaci [[:$1]] od uživatele [[User:$2|$2]] ([[User talk:$2|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), protože někdo jiný již stránku editoval nebo vrátil tuto změnu zpět.
-Poslední editaci této stránky provedl(a) [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
+Poslední editaci této stránky {{PLURAL:$3|provedl|provedla|provedl uživatel}} [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
'editcomment' => "Shrnutí editace bylo: ''„$1“''.",
'revertpage' => 'Editace uživatele „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|diskuse]]) vráceny do předchozího stavu, jehož autorem je „[[User:$1|$1]]“',
'revertpage-nouser' => 'Editace skrytého uživatele vráceny do předchozího stavu, jehož {{GENDER:$1|autorem|autorkou}} je „[[User:$1|$1]]“',
'viewtalkpage' => 'Se diskussion',
'otherlanguages' => 'Andre sprog',
'redirectedfrom' => '(Omdirigeret fra $1)',
-'redirectpagesub' => 'Omdirigering',
+'redirectpagesub' => 'Omdirigeringsside',
'lastmodifiedat' => 'Denne side blev senest ændret $1 kl. $2.',
'viewcount' => 'Siden er vist {{PLURAL:$1|en gang|$1 gange}}.',
'protectedpage' => 'Beskyttet side',
'statistics' => 'Statistik',
'statistics-header-pages' => 'Sidestatistik',
'statistics-header-edits' => 'Redigeringsstatistik',
-'statistics-header-views' => 'Visningsstatistik',
+'statistics-header-views' => 'Statistik over sidevisninger',
'statistics-header-users' => 'Statistik om brugere på {{SITENAME}}',
'statistics-header-hooks' => 'Anden statistik',
'statistics-articles' => 'Indholdssider',
'tooltip-watch' => 'Tilføj denne side til din overvågningsliste',
'tooltip-watchlistedit-normal-submit' => 'Fjern titler',
'tooltip-watchlistedit-raw-submit' => 'Opdater overvågningsliste',
-'tooltip-recreate' => 'Opret side, selv om den blev slettet.',
+'tooltip-recreate' => 'Genopret side, selv om den blev slettet.',
'tooltip-upload' => 'Upload fil',
'tooltip-rollback' => '"Rul tilbage" fjerner den sidste bidragsyders redigering(er) af denne side med et klik',
'tooltip-undo' => '"Fjern redigering" fjerner denne redigering og åbner redigeringssiden med forhåndsvisning.
'spamprotectiontext' => 'Siden du ønskede at gemme, blev blokeret af spamfilteret.
Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
'spamprotectionmatch' => 'Følgende tekst udløste vores spamfilter: $1',
-'spambot_username' => 'MediaWiki spam-rensning',
+'spambot_username' => 'MediaWikis spamoprydning',
'spam_reverting' => 'Sidste version uden henvisning til $1 gendannet.',
'spam_blanking' => 'Alle versioner, som indeholdt henvisninger til $1, er renset.',
'spam_deleting' => 'Alle versioner indeholder henvisninger til $1, sletter',
: ''$2''
Bekræft venligst, at du virkelig vil oprette denne side igen.",
'confirmrecreate-noreason' => '[[User:$1|$1]] ([[User talk:$1|diskussion]]) har slettet denne side, efter du begyndte at redigere. Bekræft venligst, at du gerne vil genoprette siden.',
-'recreate' => 'Opret igen',
+'recreate' => 'Genopret',
# action=purge
'confirm_purge_button' => 'O.k.',
'invalid-content-data' => 'Ungültige Inhaltsdaten',
'content-not-allowed-here' => 'Der Inhalt „$1“ ist auf der Seite [[$2]] nicht erlaubt',
'editwarning-warning' => 'Das Verlassen dieser Seite kann dazu führen, dass deine Änderungen verloren gehen.
-Wenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „Bearbeiten“ deiner Einstellungen abschalten.',
+Wenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „{{int:prefs-editing}}“ deiner Einstellungen abschalten.',
'editpage-notsupportedcontentformat-title' => 'Das Inhaltsformat wird nicht unterstützt',
'editpage-notsupportedcontentformat-text' => 'Das Inhaltsformat $1 wird vom Inhaltsmodell $2 nicht unterstützt.',
Bitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und speichere dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.',
'undo-failure' => 'Die Änderung konnte nicht rückgängig gemacht werden, da der betroffene Abschnitt zwischenzeitlich verändert wurde.',
'undo-norev' => 'Die Bearbeitung konnte nicht rückgängig gemacht werden, da sie nicht vorhanden ist oder gelöscht wurde.',
+'undo-nochange' => 'Anscheinend wurde diese Bearbeitung bereits rückgängig gemacht.',
'undo-summary' => 'Änderung $1 von [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) rückgängig gemacht.',
'undo-summary-username-hidden' => 'Änderung $1 eines versteckten Benutzers rückgängig gemacht.',
'last' => 'peyên',
'page_first' => 'verên',
'page_last' => 'peyên',
-'histlegend' => "Ferqê weçinayışi: Qutiya versiyonan mor ke u ''enter''i bıpıloxne ya zi makera cêrêne bıpıloxne.<br />
-Lecant: '''({{int:cur}})''' = ferqê versiyonê peyêni, '''({{int:last}})''' = ferqê versiyonê verêni, '''{{int:minoreditletter}}''' = vurnayışo werdi.",
+'histlegend' => "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />
+Cedwel: <strong>({{int:ferq}})</strong> = ferqê verziyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
'history-fieldset-title' => 'Tarixi bıvêne',
-'history-show-deleted' => 'Tenya esterıt',
+'history-show-deleted' => 'Tenya esterıtey',
'histfirst' => 'Verênêr',
'histlast' => 'Peyênêr',
'historysize' => '({{PLURAL:$1|1 bayt|$1 bayti}})',
'recentchangeslinked' => 'Vurnayışê elaqeyıni',
'recentchangeslinked-feed' => 'Vurnayışê elaqeyıni',
'recentchangeslinked-toolbox' => 'Vurnayışê elaqeyıni',
-'recentchangeslinked-title' => 'vurnayışan ser "$1"',
+'recentchangeslinked-title' => 'Heqa "$1" de vurnayışi',
'recentchangeslinked-summary' => "Lista cêrêne, pela bêlikerdiye rê (ya zi karberanê kategoriya bêlikerdiye rê) pelanê gırêdayoğan de lista de vurnayışê peyênana.
[[Special:Watchlist|Lista şımaya seyrkedışi de]] peli be nuşteyo '''qolınd''' bêli kerdê.",
'recentchangeslinked-page' => 'Nameyê pele:',
-'recentchangeslinked-to' => 'Pelayan ke ena pela ri gire bi, ser ayi vurnayışi bımoc',
+'recentchangeslinked-to' => 'Heruna pela ke yena dayene, vurnayışanê pelanê ke daye ra gırêdayiyê inan bımocne',
# Upload
'upload' => 'Dosya bar ke',
# File description page
'file-anchor-link' => 'Dosya',
'filehist' => 'Ravêrdê dosya',
-'filehist-help' => 'bıploxne ser yew tarih u aye tarih dı versionê dosya bıvin.',
+'filehist-help' => 'Seba diyayışê viyarteyê dosya tarixê ke qısımê tarix/zemani derê inan bıtıkne.',
'filehist-deleteall' => 'pêro bestere',
'filehist-deleteone' => 'bestere',
'filehist-revert' => 'reyna biyere',
# Book sources
'booksources' => 'Çımey kitaban',
-'booksources-search-legend' => 'Ser çımey kitaban bıgeyr',
+'booksources-search-legend' => 'Seba çımeyanê kıtaban cı geyre',
'booksources-isbn' => 'ISBN:',
'booksources-go' => 'Şo',
'booksources-text' => 'listeya cêrıni, keyepelê kitap rotoxan o.',
'contribsub2' => 'Qandê {{GENDER:$3|$1}} ($2)',
'nocontribs' => 'Ena kriteriya de vurnayîş çini yo.',
'uctop' => '(weziyet)',
-'month' => 'Aşm:',
-'year' => 'Ser:',
+'month' => 'Aşme:',
+'year' => 'Serre:',
'sp-contributions-newbies' => 'Tenya iştıraqanê karberanê neweyan bımocne',
'sp-contributions-newbies-sub' => 'Qe hesebê newe',
'ipbenableautoblock' => 'verniyê IPadresa peyin ê no karberi u wexta ke vurnayişi kerd ê IPadresani otomotik bıger.',
'ipbsubmit' => 'Ena karber blok bike',
'ipbother' => 'Waxtê bini:',
-'ipboptions' => '2 seat:2 hours,1 roc:1 day,3 roci:3 days,1 hefte:1 week,2 heftey:2 weeks,1 aşm:1 month,3 aşm:3 months,6 aşmi:6 months,1 ser:1 year,ebedi:infinite',
+'ipboptions' => '2 saeti:2 hours,1 roce:1 day,3 roci:3 days,1 hefte:1 week,2 heftey:2 weeks,1 aşme:1 month,3 aşmi:3 months,6 aşmi:6 months,1 serre:1 year,ebedi:infinite',
'ipbhidename' => 'Nameyê karberî listeyan u vurnayîşan ra binumne',
'ipbwatchuser' => 'Pela miniqaşe u pela ena karberî seyr bike',
'ipb-disableusertalk' => 'No karber wexto ke bloqedeyo wa pela da xodı vurnayış kerdışi rê izin medı',
'tooltip-ca-nstab-help' => 'Pela peşti bıvêne',
'tooltip-ca-nstab-category' => 'Pela kategoriye bıvêne',
'tooltip-minoredit' => 'Nay vırnayışa werdi nışan bıkeré',
-'tooltip-save' => 'Vurnayışa qeyd ke',
+'tooltip-save' => 'Vurnayışanê xo qeyd ke',
'tooltip-preview' => 'Vurnayışané ğo çımra ravyarné. Verdé qeyd kerdışi eneri bıkarné!',
'tooltip-diff' => 'Metni sero vurnayışan mocneno',
'tooltip-compareselectedversions' => 'Ena per de ferqê rewziyonan de dı weçinaya bıvinê',
'passwordreset-capture-help' => "S' es sernés cla caşèla ché, l'indirés ed pôsta eletrônica (cun la cêva 'd ingrès pruvişôria), év vîn fâ vèder, d'ed là 'd èser spidî a l'utèint.",
'passwordreset-email' => 'Indirés pôsta eletrônica',
'passwordreset-emailtitle' => "Particulêr ed l'utèint só {{SITENAME}}",
+'passwordreset-emailtext-ip' => "Quelchidûn (prubabilmèint té, cun l'indirés IP $1) l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:
+
+$2
+
+{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès.
+
+Se t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia.",
+'passwordreset-emailtext-user' => "L'utèint $1 ed {{SITENAME}} l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:
+
+$2
+
+{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria ché la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès.
+
+Se t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia",
+'passwordreset-emailelement' => "Nòm utèint: $1.
+Cêva 'd ingrès pruvişôria: $2",
+'passwordreset-emailsent' => "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès.",
+'passwordreset-emailsent-capture' => "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, ché sòta a gh'é al tèst che gh'é scrét.",
+'passwordreset-emailerror-capture' => "É stê fât un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, scréta ché 'd sègvit. La spedisiòun {{GENDER:$2|a l'utèint}} an n'é mia 'riusîda:$1",
+
+# Special:ChangeEmail
+'changeemail' => "Câmbia l'indirés ed la pôsta eletrônica",
+'changeemail-header' => "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
+'changeemail-text' => "Impés sté mòdul per cambiêr al tó indirés ed pòsta eletrônica. A srà necesâri mèter dèinter la cêva 'd ingrès per cunfermêr la mudéfica.",
+'changeemail-no-info' => "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
+'changeemail-oldemail' => "L'indirés ed la pôsta eletrànica 'd adès.",
+'changeemail-newemail' => 'Nōv indirés ed pàsta eletrônica:',
+'changeemail-none' => '(nisûn)',
+'changeemail-password' => "La cêva 'd ingrès só {{SITENAME}}:",
+'changeemail-submit' => "Cambiêr l'indirés ed pôsta eletrônica",
+'changeemail-cancel' => 'Scanşèla',
+'changeemail-throttled' => "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr dôp.",
+
+# Special:ResetTokens
+'resettokens' => "Tōrna 'd impustêr la cêva",
+'resettokens-text' => "Ché 't pō turnêr a impustêr al cêvi ch'ét permèten l'ingrès a precîşi infurmasiòun privêdi lighêdi a la tó utèinsa. Ét duvrés fêrel se per chêş ét j ê spartîdi cun quelchidûn o se al j infurmasiòun ed la tó utèinsa în in perécol.",
+'resettokens-no-tokens' => "An gh'é mìa di token da turnêr a impustêr.",
+'resettokens-legend' => "Tōrna 'd impustêr la cêva",
+'resettokens-token-label' => "$1 (valōr 'd adèsa: $2)",
+'resettokens-watchlist-token' => "Token p'r al feed web (Atom/RSS) dal [[Special:Watchlist|mudéfichi al pàgini ch'ét tîn sòt' ôc]]",
+'resettokens-done' => 'Token turnê a impustêr.',
+'resettokens-resetbutton' => 'Més a zēro i token sernî',
# Edit page toolbar
'bold_sample' => 'Grasèt',
# Edit pages
'summary' => 'Sûnt:',
+'subject' => 'Argumèint (tétol):',
'minoredit' => "Còsta l'é 'na mudéfica céca",
'watchthis' => 'Tîn adrē a cla pàgina ché',
'savearticle' => 'Sêlva la pàgina',
'preview' => 'Guêrda préma',
'showpreview' => "Guêrda préma 'd salvêr",
+'showlivepreview' => 'Guêrda préma diretamèint',
'showdiff' => 'Guêrda i cambiamèint',
'anoneditwarning' => "'''Atensiòun:''' Ingrès mìa fât. Al tó indirés IP al srà sgnê int la stòria ed cla pàgina chè.",
+'anonpreviewwarning' => "\"An n'é mìa stê fât l'ingrès. Mèinter es sêlva la pàgina, l'indirés IP al srà sgnê int la stòria 'd la pàgina.\"",
'blockedtitle' => 'Utèint bluchê',
'newarticle' => '(Nōv)',
'newarticletext' => "Al colegamèint apèina fât al cumbîna cun 'na pàgina ch' an n'é mìa incòra stêda fâta. S'ét vō fêr la pàgina adès, l'é asê cumincêr a scréver al tèst int la caşèla ché sòt (per vedèr infurmasiòun pió precîşi guêrda la [[{{MediaWiki:Helppage}}|pàgina 'd ajót]]). Se al colegamèint l'é stê avêrt per erōr, l'é asê clichêr al pulsânt \"Indrē\" dal tó navigadōr.",
'content-failed-to-parse' => 'Απέτυχε η ανάλυση περιεχομένου του $2 για το μοντέλο $1:$3',
'invalid-content-data' => 'Μη έγκυρα δεδομένα περιεχομένου',
'content-not-allowed-here' => 'Το περιεχόμενο «$1» δεν επιτρέπεται στη σελίδα [[$2]]',
-'editwarning-warning' => 'Αφήνοντας αυτή τη σελίδα μπορεί να σας κάνει να χάσετε κάποιες αλλαγές που έχετε κάνει.
-Αν έχετε συνδεθεί, μπορείτε να απενεργοποιήσετε αυτή την προειδοποίηση στην ενότητα "Επεξεργασία" των προτιμήσεών σας.',
+'editwarning-warning' => 'Αφήνοντας αυτή τη σελίδα μπορεί να έχει ως συνέπεια να χαθούν κάποιες αλλαγές που έχετε κάνει.
+Αν έχετε συνδεθεί, μπορείτε να απενεργοποιήσετε αυτή την προειδοποίηση στην ενότητα "{{int:prefs-editing}}" των προτιμήσεών σας.',
# Content models
'content-model-wikitext' => 'βικικείμενο',
'version-hook-subscribedby' => 'Υπογεγραμμένο από',
'version-version' => '(Έκδοση $1)',
'version-license' => 'Άδεια χρήσης',
+'version-ext-license' => 'Άδεια χρήσης',
+'version-ext-colheader-name' => 'Επέκταση',
+'version-ext-colheader-version' => 'Έκδοση',
+'version-ext-colheader-license' => 'Άδεια χρήσης',
+'version-ext-colheader-description' => 'Περιγραφή',
'version-poweredby-credits' => "Αυτό το wiki λειτουργεί με το λογισμικό '''[https://www.mediawiki.org/ MediaWiki]''', πνευματική ιδιοκτησία © 2001-$1 $2.",
'version-poweredby-others' => 'άλλοι',
'version-poweredby-translators' => 'translatewiki.net μεταφραστές',
Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.',
'undo-failure' => 'The edit could not be undone due to conflicting intermediate edits.',
'undo-norev' => 'The edit could not be undone because it does not exist or was deleted.',
+'undo-nochange' => 'The edit appears to have already been undone.',
'undo-summary' => 'Undo revision $1 by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])',
'undo-summary-username-hidden' => 'Undo revision $1 by a hidden user',
'searchrelated' => 'related',
'searchall' => 'all',
'showingresults' => "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} starting with #<strong>$2</strong>.",
+'showingresultsinrange' => "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} in range #<strong>$2</strong> to #<strong>$3</strong>.",
'showingresultsnum' => "Showing below {{PLURAL:$3|<strong>1</strong> result|<strong>$3</strong> results}} starting with #<strong>$2</strong>.",
'showingresultsheader' => "{{PLURAL:$5|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 - $2</strong> of <strong>$3</strong>}} for <strong>$4</strong>",
'search-nonefound' => 'There were no results matching the query.',
'contribslink' => 'contribs',
'emaillink' => 'send email',
'autoblocker' => 'Autoblocked because your IP address has been recently used by "[[User:$1|$1]]".
-The reason given for $1\'s block is "<em>$2</em>"',
+The reason given for $1\'s block is "$2"',
'blocklogpage' => 'Block log',
'blocklog-showlog' => 'This user has been blocked previously.
The block log is provided below for reference:',
'invalid-content-data' => 'Vigased sisuandmed',
'content-not-allowed-here' => 'Lehekülg [[$2]] ei või sisaldada $1i.',
'editwarning-warning' => 'Sellelt leheküljelt lahkumise tõttu võivad tehtud muudatused kaotsi minna.
-Kui oled sisse loginud, saad selle hoiatuse eelistuste alaosas "Toimetamine" keelata.',
+Kui oled sisse loginud, saad selle hoiatuse eelistuste alaosas "{{int:prefs-editing}}" keelata.',
'editpage-notsupportedcontentformat-title' => 'Sisuvormingu tugi puudub',
'editpage-notsupportedcontentformat-text' => 'Sisumudelil $2 puudub sisuvormingu $1 tugi.',
'showhideselectedversions' => 'Muuda valitud redaktsioonide nähtavust',
'editundo' => 'eemalda',
'diff-empty' => '(Erinevus puudub)',
+'diff-multi-sameuser' => '(ei näidata sama kasutaja {{PLURAL:$1|üht|$1}} vahepealset redaktsiooni)',
+'diff-multi-otherusers' => '(ei näidata {{PLURAL:$2|ühe teise|$2}} kasutaja {{PLURAL:$1|üht|$1}} vahepealset redaktsiooni)',
'diff-multi-manyusers' => '({{PLURAL:$1|Ühte|$1}} vahepealset rohkem kui {{PLURAL:$2|ühe|$2}} kasutaja redaktsiooni ei näidata.)',
'difference-missing-revision' => 'Selle erinevuste vaate {{PLURAL:$2|üht|$2}} redaktsiooni ($1) ei leitud.
'content-failed-to-parse' => 'عدم موفقیت در تجزیه محتوای $2 برای مدل $1: $3',
'invalid-content-data' => 'داده محتوای نامعتبر',
'content-not-allowed-here' => 'محتوای «$1» در صفحهٔ [[$2]] مجاز نیست',
-'editwarning-warning' => 'خرÙ\88ج از اÛ\8cÙ\86 صÙ\81ØÙ\87 Ù\85Ù\85Ú©Ù\86 است باعث از دست رÙ\81تÙ\86 Ù\87رÚ\86Ù\87 Ù\86Ù\88شتÙ\87â\80\8cاÛ\8cد Ø´Ù\88د.
-اگر شما با نام کاربری وارد شدهاید میتوانید این هشدار را در بخش «در حال ویرایش» ترجیحاتتان بیابید.',
+'editwarning-warning' => 'خرÙ\88ج از اÛ\8cÙ\86 صÙ\81ØÙ\87 Ù\85Ù\85Ú©Ù\86 است باعث Ø´Ù\88د Ú©Ù\87 Ø´Ù\85ا Ù\87ر شاÙ\86سÛ\8c Ú©Ù\87 بÙ\87 Ù\88جÙ\88د Ø¢Ù\88ردÙ\87 اÛ\8cد را از دست بدÙ\87Û\8cد.
+اگر شما وارد سیستم شدهاید، میتوانید این هشدار را در بخش «در حال ویرایش» ترجیحاتتان غیرفعال کنید.',
'editpage-notsupportedcontentformat-title' => 'فرمت محتوا پشتیبانی نشده',
'editpage-notsupportedcontentformat-text' => 'فرمت محتوای $1 توسط مدل محتوای $2 پشتیبانی نشدهاست.',
'showhideselectedversions' => 'نمایش/نهفتن نسخههای انتخاب شده',
'editundo' => 'خنثیسازی',
'diff-empty' => '(بدون تفاوت)',
+'diff-multi-sameuser' => '({{PLURAL:$1|یک نسخهٔ متوسط|$1 نسخههای متوسط}} توسط کاربر مشابهی که نشان داده نشده)',
+'diff-multi-otherusers' => '({{PLURAL:$1|یک نسخهٔ متوسط|$1 نسخههای متوسط}} توسط {{PLURAL:$2|کاربر دیگری|$2 کاربران}} نشان داده نشده)',
'diff-multi-manyusers' => '({{PLURAL:$1|یک|$1}} ویرایش میانی توسط بیش از {{PLURAL:$2|یک|$2}} کاربر نشان داده نشدهاست)',
'difference-missing-revision' => '{{PLURAL:$2|یک ویرایش|$2 ویرایش}} از تفاوت نسخهها ($1) {{PLURAL:$2|یافت|یافت}} نشد.
'shown-title' => 'نمایش $1 {{PLURAL:$1|نتیجه|نتیجه}} در هر صفحه',
'viewprevnext' => 'نمایش ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''صفحهای با عنوان «[[:$1]]» در این ویکی وجود دارد.'''",
-'searchmenu-new' => "'''صفحهٔ «[[:$1]]» را در این ویکی بسازید!'''",
+'searchmenu-new' => '<strong>ایجاد صفحه "[[:$1]]" در این ویکی!</strong> {{PLURAL:$2|0=|همچنین مشاهدهٔ صفحهٔ پیدا شده با جستجوی شما.|همچنین مشاهدهٔ جستجوی نتایج پیدا شده.}}',
'searchprofile-articles' => 'صفحههای محتوایی',
'searchprofile-project' => 'صفحههای راهنما و پروژه',
'searchprofile-images' => 'چندرسانهای',
'watchmethod-list' => 'بررسی صفحههای مورد پیگیری برای ویرایشهای اخیر',
'watchlistcontains' => 'فهرست پیگیریهای شما حاوی $1 {{PLURAL:$1|صفحه|صفحه}} است.',
'iteminvalidname' => 'مشکل با مورد «$1»، نام نامعتبر است...',
+'wlnote2' => 'در زیر تغییرات اخیر وجود دارد {{PLURAL:$1|ساعت|<strong>$1</strong> ساعتها}}, به عنوان $2, $3.',
'wlshowlast' => 'نمایش آخرین $1 ساعت $2 روز $3',
'watchlist-options' => 'گزینههای پیگیری',
'import-error-special' => 'صفحهٔ «$1» درونریزی نشد، چرا که متعلق به فضای نام نامجاز است.',
'import-error-invalid' => 'صفحه "$1" به دلیل نامعتبر بودن نامش وارد نمیشود.',
'import-error-unserialize' => 'امکان خارج کردن نسخهٔ $2 از صفحهٔ «$1» از حالت سریالشده وجود نداشت. گزارش شد که نسخه از مدل محتوای $3 استفاده میکند که به صورت $4 سریال شدهاست.',
+'import-error-bad-location' => 'بازبینی $2 با استفاده از مدل محتوای $3 نمیتواند در "$1" در این ویکی ذخیره شده باشد، از آنجایی که مدل در آن صفحه پشتیبانی نشدهاست.',
'import-options-wrong' => '{{PLURAL:$2|جزئیات|جزئیات}} اشتباه: <nowiki>$1</nowiki>',
'import-rootpage-invalid' => 'با توجه به ریشه صفحه عنوان نامعتبر است.',
'import-rootpage-nosubpage' => 'فضای نام "$1" صفحهٔ مبنا اجازهٔ زیرصفحه نمیدهد.',
'versionrequiredtext' => 'La version $1 de MediaWiki est nécessaire pour utiliser cette page. Consultez [[Special:Version|la page des versions]]',
'ok' => 'Valider',
+'pagetitle' => '$1 — {{SITENAME}}',
'retrievedfrom' => 'Récupérée de « $1 »',
'youhavenewmessages' => '{{PLURAL:$3|Vous avez}} $1 ($2).',
'youhavenewmessagesfromusers' => "{{PLURAL:$4|Vous avez}} $1 {{PLURAL:$3|d'un autre utilisateur|de $3 autres utilisateurs}} ($2).",
'template-semiprotected' => '(semi-protégé)',
'hiddencategories' => '{{PLURAL:$1|Catégorie cachée|Catégories cachées}} dont cette page fait partie :',
'edittools' => '<!-- Tout texte entré ici sera affiché sous les boîtes de modification ou les formulaires de téléversement de fichier. -->',
+'edittools-upload' => '—',
'nocreatetext' => '{{SITENAME}} a restreint la possibilité de créer de nouvelles pages.
Vous pouvez revenir en arrière et modifier une page existante, ou bien [[Special:UserLogin|vous connecter ou créer un compte]].',
'nocreate-loggedin' => "Vous n'avez pas la permission de créer de nouvelles pages.",
'invalid-content-data' => 'Données du contenu non valides',
'content-not-allowed-here' => 'Le contenu « $1 » n’est pas autorisé sur la page [[$2]]',
'editwarning-warning' => 'Quitter cette page vous fera perdre toutes les modifications que vous avez faites.
-Si vous êtes connecté, vous pouvez désactiver cet avertissement dans la section « Modification » de vos préférences.',
+Si vous êtes connecté, vous pouvez désactiver cet avertissement dans la section « {{int:prefs-editing}} » de vos préférences.',
'editpage-notsupportedcontentformat-title' => 'Format de contenu non pris en charge',
'editpage-notsupportedcontentformat-text' => "Le format de contenu $1 n'est pas pris en charge par le modèle de contenu $2 .",
'undo-success' => 'Cette modification va être défaite. Veuillez vérifier les modifications ci-dessous, puis publier si c’est bien ce que vous voulez faire.',
'undo-failure' => 'Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.',
'undo-norev' => 'La modification n’a pas pu être défaite parce qu’elle est inexistante ou qu’elle a été supprimée.',
+'undo-nochange' => 'Il semble que la modification aie déjà été annulée.',
'undo-summary' => 'Annulation des modifications $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])',
'undo-summary-username-hidden' => 'Annuler la révision $1 par un utilisateur masqué',
'mergehistory-comment' => '[[:$1]] fusionnée avec [[:$2]] : $3',
'mergehistory-same-destination' => "Les pages d'origine et de destination ne peuvent pas être la même",
'mergehistory-reason' => 'Motif :',
+'mergehistory-revisionrow' => '$1 ($2) $3 — $4 $5 $6',
# Merge log
'mergelog' => 'Journal des fusions',
'showhideselectedversions' => 'Afficher/masquer les versions sélectionnées',
'editundo' => 'annuler',
'diff-empty' => '(Aucune différence)',
+'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}})",
'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}}.
'shown-title' => 'Afficher $1 résultat{{PLURAL:$1||s}} par page',
'viewprevnext' => 'Voir ($1 {{int:pipe-separator}} $2) ($3).',
'searchmenu-exists' => "'''Il existe une page nommée « [[:$1]] » sur ce wiki.''' {{PLURAL:$2|0=|Voyez également les autres résultats de votre recherche.}}",
-'searchmenu-new' => "'''Créer la page « [[:$1|$1]] » sur ce wiki !''' {{PLURAL:$2|0=|Voyez également la page trouvée avec votre recherche.|Voyez également les résultats de votre recherche.}}",
+'searchmenu-new' => '<strong>Créer la page « [[:$1|$1]] » sur ce wiki !</strong> {{PLURAL:$2|0=|Voyez également la page trouvée avec votre recherche.|Voyez également les résultats de votre recherche.}}',
'searchprofile-articles' => 'Pages de contenu',
'searchprofile-project' => "Pages d'aide et de projet",
'searchprofile-images' => 'Multimédia',
$1',
'undelete-show-file-confirm' => 'Êtes-vous sûr de vouloir visionner une version supprimée du fichier « <nowiki>$1</nowiki> » datant du $2 à $3 ?',
'undelete-show-file-submit' => 'Oui',
+'undelete-revision-row' => '$1 $2 ($3) $4 — $5 $6 $7 $8 $9',
# Namespace form on various pages
'namespace' => 'Espace de noms :',
'print.css' => '/* Le CSS placé ici affectera les impressions */',
'noscript.css' => '/* Le CSS placé ici affectera les utilisateurs ayant désactivé Javascript. */',
'group-autoconfirmed.css' => '/* Le CSS placé ici affectera les utilisateurs auto-confirmés seulement. */',
+'group-user.css' => '/* Le CSS placé ici n’affectera que les utilisateurs enregistrés. */',
'group-bot.css' => '/* Le CSS placé ici affectera les robots seulement. */',
'group-sysop.css' => '/* Le CSS inclus ici n’affectera que les administrateurs */',
'group-bureaucrat.css' => '/* Le CSS inclus ici n’affectera que les bureaucrates */',
'modern.js' => '/* Tout JavaScript ici sera chargé avec les pages accédées par les utilisateurs de l’habillage Moderne uniquement */',
'vector.js' => '/* Tout code JavaScript placé ici sera chargé pour les utilisateurs de l’habillage Vector */',
'group-autoconfirmed.js' => '/* Le JavaScript inclus ici n’affectera que les utilisateurs auto-confirmés */',
+'group-user.js' => '/* Le JavaScript placé ici ne sera chargé que pour les utilisateurs enregistrés. */',
'group-bot.js' => '/* Le JavaScript inclus ici n’affectera que les robots */',
'group-sysop.js' => '/* Le JavaScript inclus ici n’affectera que les administrateurs */',
'group-bureaucrat.js' => '/* Le JavaScript inclus ici n’affectera que les bureaucrates */',
Si vous l'exécutez, votre système peut être compromis.",
'imagemaxsize' => "Taille maximale des images :<br />''(pour les pages de description de fichier)''",
'thumbsize' => 'Taille de la miniature :',
+'widthheight' => '$1 × $2',
'widthheightpage' => '$1 × $2, $3 page{{PLURAL:$3||s}}',
'file-info' => 'Taille du fichier : $1, type MIME : $2',
'file-info-size' => '$1 × $2 pixels, taille du fichier : $3, type MIME : $4',
'sp-newimages-showfrom' => 'Afficher les nouveaux fichiers à partir du $1 à $2',
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1 s',
+'minutes-abbrev' => '$1 min',
+'hours-abbrev' => '$1 h',
'days-abbrev' => '$1 j',
'seconds' => '{{PLURAL:$1|$1 seconde|$1 secondes}}',
'minutes' => '{{PLURAL:$1|$1 minute|$1 minutes}}',
Seules les listes d’énumération (commençant par *) sont prises en compte. Le premier lien d’une ligne doit être celui d’une mauvaise image.
Les autres liens sur la même ligne sont considérés comme des exceptions, par exemple des pages sur lesquelles l’image peut apparaître.',
+# Variants for Kurdish language
+'variantname-ku-arab' => 'ku-arab',
+'variantname-ku-latn' => 'ku-latn',
+
+# Variants for Tajiki language
+'variantname-tg-cyrl' => 'tg-cyrl',
+'variantname-tg-latn' => 'tg-latn',
+
+# Variants for Inuktitut language
+'variantname-ike-cans' => 'ike-cans',
+'variantname-ike-latn' => 'ike-latn',
+
+# Variants for Tachelhit language
+'variantname-shi-tfng' => 'shi-tfng',
+'variantname-shi-latn' => 'shi-latn',
+
# Metadata
'metadata' => 'Métadonnées',
'metadata-help' => "Ce fichier contient des informations supplémentaires, probablement ajoutées par l'appareil photo numérique ou le numériseur utilisé pour le créer. Si le fichier a été modifié depuis son état original, certains détails peuvent ne pas refléter entièrement l'image modifiée.",
'exif-originalimageheight' => "Hauteur de l'image avant qu'elle ait été recadrée",
'exif-originalimagewidth' => "Largeur de l'image avant qu'elle ait été recadrée",
+# Make & model, can be wikified in order to link to the camera and model name
+'exif-contact-value' => '$1
+
+$2
+<div class="adr">
+$3
+
+$6 $4, $5
+
+$7
+</div>
+$8',
+
# Exif attributes
'exif-compression-1' => 'Non compressé',
'exif-compression-2' => 'CCITT Groupe 3 Longueur du codage Huffman modifié de dimension 1',
'autosumm-new' => 'Page créée avec « $1 »',
# Size units
-'size-bytes' => '$1 o',
-'size-kilobytes' => '$1 Kio',
-'size-megabytes' => '$1 Mio',
-'size-gigabytes' => '$1 Gio',
-'size-terabytes' => '$1 Tio',
-'size-petabytes' => '$1 Pio',
+'size-bytes' => '$1 o',
+'size-kilobytes' => '$1 Kio',
+'size-megabytes' => '$1 Mio',
+'size-gigabytes' => '$1 Gio',
+'size-terabytes' => '$1 Tio',
+'size-petabytes' => '$1 Pio',
'size-exabytes' => '$1 Eio',
-'size-zetabytes' => '$1 Zio',
+'size-zetabytes' => '$1 Zio',
'size-yottabytes' => '$1 Yio',
+# Bitrate units
+'bitrate-bits' => '$1 bps',
+'bitrate-kilobits' => '$1 kbps',
+'bitrate-megabits' => '$1 Mbps',
+'bitrate-gigabits' => '$1 Gbps',
+'bitrate-terabits' => '$1 Tbps',
+'bitrate-petabits' => '$1 Pbps',
+'bitrate-exabits' => '$1 Ebps',
+'bitrate-zetabits' => '$1 Zbps',
+'bitrate-yottabits' => '$1 Ybps',
+
# Live preview
'livepreview-loading' => 'Chargement...',
'livepreview-ready' => 'Chargement … terminé !',
'retypenew' => 'Skriiw det paaswurd noch ans weder hen:',
'resetpass_submit' => 'Paaswurd saat an uunmelde',
'changepassword-success' => 'Din paaswurd as feranert wurden!',
+'changepassword-throttled' => 'Dü heest tufölsis fersoocht, di uuntumeldin.
+Wees so gud an teew $1, iar dü det noch ans ferschükst.',
'resetpass_forbidden' => 'Det paaswurd koon ei feranert wurd.',
'resetpass-no-info' => 'Dü skel di uunmelde, am üüb det sidj tutugripen.',
'resetpass-submit-loggedin' => 'Paaswurd feranre',
'changeemail-password' => 'Din {{SITENAME}} paaswurd:',
'changeemail-submit' => 'E-mail adres feranre',
'changeemail-cancel' => 'Ufbreeg',
+'changeemail-throttled' => 'Dü heest tufölsis fersoocht, di uuntumeldin.
+Wees so gud an teew $1, iar dü det noch ans ferschükst.',
# Special:ResetTokens
'resettokens' => 'Tokens turagsaat',
'invalid-content-data' => 'Diar stäänt wat uun, wat diar ei hen hiart',
'content-not-allowed-here' => '„$1“ mut ei skrewen wurd üüb sidj [[$2]]',
'editwarning-warning' => 'Wan dü detheer sidj slotst, kön feranrangen ferleesen gung.
-Üs uunmeldet brüker könst dü detheer wäärnang bi din iinstelangen oner „Bewerke“ wechknipse.',
+Üs uunmeldet brüker könst dü detheer wäärnang bi din iinstelangen oner „{{int:prefs-editing}}“ ufstel.',
'editpage-notsupportedcontentformat-title' => 'Detdiar formoot gongt ei.',
'editpage-notsupportedcontentformat-text' => 'Det formoot $1 gongt ei mä det model $2.',
'showhideselectedversions' => 'Werjuunen wise of fersteeg',
'editundo' => 'turagsaat',
'diff-empty' => '(nään ferskeel)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan disalew brüker {{PLURAL:$1|woort|wurd}} ei uunwiset)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan {{PLURAL:$2|ään öödern brüker|$2 ööder brükern}} {{PLURAL:$1|woort|wurd}} ei uunwiset)',
'diff-multi-manyusers' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan muar üs $2 {{PLURAL:$2|brüker|brükern}} wurd ei uunwiset)',
'difference-missing-revision' => "{{PLURAL:$2|Ian werjuun|$2 werjuunen}} faan di ferskeel ($1) {{PLURAL:$2|as|san}} ei fünjen wurden.
'shown-title' => 'Wise $1 {{PLURAL:$1|resultaat|resultaaten}} per sidj',
'viewprevnext' => 'Wise ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''Deer as en sid nååmd \"[[:\$1]]\" önj jüdeer Wiki'''",
-'searchmenu-new' => "'''Maage det sidj „[[:$1]]“ uun detheer wiki.'''",
+'searchmenu-new' => '<strong>Maage det sidj „[[:$1]]“ uun detheer wiki!</strong> {{PLURAL:$2|0=|Luke uk bi det fünjen sidj.|Luke uk bi a fünjen sidjen.}}',
'searchprofile-articles' => 'Artiikler',
'searchprofile-project' => 'Halep- an Projektsidjen',
'searchprofile-images' => 'Multimedia',
'search-result-score' => 'Relewans: $1 %',
'search-redirect' => '(widjerfeerd faan „$1“)',
'search-section' => '(kirew $1)',
+'search-file-match' => '(fünjen tekst)',
'search-suggest' => 'Mendst dü „$1“?',
'search-interwiki-caption' => 'Saster-projekten',
'search-interwiki-default' => '$1 resultaaten:',
'watchmethod-list' => "Sidjen, diar dü uun't uug heest, am a leetst feranrangen beluke",
'watchlistcontains' => "Dü häälst $1 {{PLURAL:$1|sidj|sidjen}} uun't uug.",
'iteminvalidname' => 'Mä di iindrach „$1“ stemet wat ei, di nööm as ferkiard.',
+'wlnote2' => 'Diar stun a feranrangen faan a leetst {{PLURAL:$1|stünj|<strong>$1</strong> stünjen}}, üüb a stant faan $2, $3.',
'wlshowlast' => 'Wise a feranrangen faan leetst $1 stünjen, $2 daar of $3.',
'watchlist-options' => "Iinstelangen för't uunwisin",
'delete-edit-reasonlist' => "Grünjer för't striken bewerke",
'delete-toobig' => 'Detdiar sidj hää muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} . Sok sidjen kön ei so gau stregen wurd, ööders san a servers plaat.',
'delete-warning-toobig' => "Detdiar sidj hää muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} . Det striken koon komer maage bi't dootenbeenk.",
-'deleting-backlinks-warning' => "'''Paase üüb:''' Diar ferwise noch ööder sidjen üüb det sidj, diar dü strik wel.",
+'deleting-backlinks-warning' => "'''Paase üüb:''' Diar ferwise noch ööder sidjen üüb det sidj, diar dü strik wel. Of det sidj as noch huarööders iinbünjen.",
# Rollback
'rollback' => 'Feranrangen turagsaat',
'range_block_disabled' => 'Det mögelkhaid, hialer adresrümer tu sperin, as ei aktiif.',
'ipb_expiry_invalid' => 'Didiar tidjrüm gongt ei.',
'ipb_expiry_temp' => 'Ferbürgen brükernööm-speren skel permanent wees.',
-'ipb_hide_invalid' => 'Detdiar brükerkonto koon ei ferbürgen wurd, auer diar tuföl feranrangen uun a ferluup stun.',
+'ipb_hide_invalid' => 'Detdiar brükerkonto koon ei ferbürgen wurd, auer diar muar üs {{PLURAL:$1|ian feranrang|$1 feranrangen}} uun a ferluup stun.',
'ipb_already_blocked' => '„$1“ as al speret',
'ipb-needreblock' => '$1 as al speret. Wel dü a speriinstelangen feranre?',
'ipb-otherblocks-header' => 'Ööder {{PLURAL:$1|sper|speren}}',
'allmessages-prefix' => 'Filter mä prefix:',
'allmessages-language' => 'Spriak:',
'allmessages-filter-submit' => 'Widjer',
+'allmessages-filter-translate' => 'Auersaat',
# Thumbnails
'thumbnail-more' => 'Fergratre',
'importuploaderrortemp' => "Bi't huuchschüüren faan det importdatei as wat skiaf gingen. Diar as nian tidjwiis fertiaknis.",
'import-parse-failure' => "Bi't importiarin faan det XML-datei as wat skiaf gingen.",
'import-noarticle' => 'Diar as nian sidj tu importiarin bestemet wurden.',
-'import-nonewrevisions' => 'Aal jodiar werjuunen san al ans importiaret wurden.',
+'import-nonewrevisions' => 'Diar wurd nian werjuunen importiaret, auer jo eder al diar wiar of auersprüngen wurden san.',
'xml-error-string' => '$1 uun rä $2, türn $3 (byte $4): $5',
'import-upload' => 'XML-datein importiare',
'import-token-mismatch' => 'Session dooten san wech. Ferschük det noch ans weder.',
'import-error-special' => 'Det sidj „$1“ as ei importiaret wurden, auer hat tu en nöömrüm hiart, huar nian sidjen mögelk san.',
'import-error-invalid' => 'Det sidj „$1“ as ei importiaret wurden, auer di nööm ei stemet.',
'import-error-unserialize' => 'Det werjuun $2 faan det sidj „$1“ küd ei deserialisiaret wurd. Det werjuun woort mä det münster $3 brükt, an det as mä $4 serialisiaret.',
+'import-error-bad-location' => 'Det feranrang $2 mä model $3 koon ei üs "$1" üüb detheer wiki seekert wurd, auer detdiar model heer ei brükt wurd koon.',
'import-options-wrong' => 'Ferkiard {{PLURAL:$2|iinstelang|iinstelangen}}: <nowiki>$1</nowiki>',
'import-rootpage-invalid' => 'Didiar sidjennööm as ferkiard.',
'import-rootpage-nosubpage' => 'Uun di nöömrüm „$1“ jaft at nian onersidjen.',
'expand_templates_generate_rawhtml' => 'Rä HTML uunwise',
'expand_templates_preview' => 'Föörskau',
+# Unknown messages
+'createaccount-hook-aborted' => '$1',
+'uploadinvalidxml' => "Det XML uun det huuchschüürd datei küd ei ''parset'' wurd.",
);
# File backend
'backend-fail-stream' => 'Non se puido transmitir o ficheiro "$1".',
'backend-fail-backup' => 'Non se puido facer unha copia de seguridade do ficheiro "$1".',
-'backend-fail-notexists' => 'Non existe o ficheiro "$1".',
+'backend-fail-notexists' => 'O ficheiro "$1" non existe.',
'backend-fail-hashes' => 'Non se puideron obter os cardinais do ficheiro por comparación.',
'backend-fail-notsame' => 'Xa existe un ficheiro chamado "$1", con contidos diferentes.',
'backend-fail-invalidpath' => '"$1" non é unha ruta de almacenamento válida.',
'oct' => 'JFou',
'nov' => 'Soun',
'dec' => 'Noll',
+'january-date' => '$1 Jerrey Geuree',
+'february-date' => '$1 Toshiaght Arree',
+'march-date' => '$1 Mayrnt',
+'april-date' => '$1 Averil',
+'may-date' => '$1 Boaldyn',
+'june-date' => '1 Mean Souree',
+'july-date' => '$1 Jerrey Souree',
+'august-date' => '$1 Luanistyn',
+'september-date' => '$1 Mean Fouyir',
+'october-date' => '$1 Jerrey Fouyir',
+'november-date' => '$1 Sauin',
+'december-date' => '$1 Mee ny Nollick',
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Ronney|Ronnaghyn}}',
'view' => 'Lhaih',
'edit' => 'Reagh',
'create' => 'Croo',
-'editthispage' => 'Reagh yn duillag shoh',
+'editthispage' => 'Reagh y duillag shoh',
'create-this-page' => 'Croo yn duillag shoh',
'delete' => 'Scryss',
'deletethispage' => 'Scryss y duillag shoh',
+'undeletethispage' => 'Jee-scryss y duillag shoh',
'undelete_short' => 'Jee-scryss {{PLURAL:$1|$1 caghlaa|$1 chaghlaa|$1 chaghlaa|$1 caghlaaghyn}}',
'viewdeleted_short' => 'Jeeagh er {{PLURAL:$1|$1 caghlaa scryssit magh|$1 chaghlaa scryssit magh|$1 chaghlaa scryssit magh|$1 caghlaaghyn scryssit magh}}',
'protect' => 'Coadee',
'nchanges' => '$1 {{PLURAL:$1|caghlaa|chaghlaa|chaghlaa|caghlaaghyn}}',
'recentchanges' => "Caghlaaghyn s'noa",
'recentchanges-legend' => "Reihyssyn da ny caghlaaghyn s'noa",
-'recentchanges-summary' => "Shirrey ny caghlaaghyn s'noa da'n wiki er y duillag shoh.",
+'recentchanges-summary' => "Shirr ny caghlaaghyn s'noa da'n wiki er y duillag shoh.",
'recentchanges-feed-description' => "Shirr ny caghlaaghyn s'noa er y wiki 'sy scoltey shoh.",
'recentchanges-label-newpage' => 'Ren y reaghey shoh croo duillag noa',
'recentchanges-label-minor' => 'She myn-reaghey eh shoh',
'recentchanges-label-bot' => 'Ren bot y reaghey shoh',
'rcnotefrom' => "Shoh heese ny caghlaaghyn veih '''$2''' (gys '''$1''' taishbynit).",
'rclistfrom' => "Taishbyn ny caghlaaghyn s'noa veih $1",
-'rcshowhideminor' => '{{PLURAL:$1|$1 myn-arraghey|$1 vyn-arraghey|$1 vyn-arraghey|$1 myn-arraghyn}}',
+'rcshowhideminor' => '$1 myn-arraghyn',
'rcshowhidebots' => '{{PLURAL:$1|$1 robot|$1 robot|$1 robot|$1 robotyn}}',
'rcshowhideliu' => '{{PLURAL:$1|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyryn}} ta loggit stiagh',
'rcshowhideanons' => '{{PLURAL:$1|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyryn}} neuenmyssit',
* @author Rotem Liss (March 2006 on)
* @author Rotemliss
* @author YaronSh
+ * @author Yona b
* @author אור שפירא
* @author דולב
* @author ערן
'retypenew' => 'חזרה על הסיסמה החדשה:',
'resetpass_submit' => 'הגדרת הסיסמה וכניסה לחשבון',
'changepassword-success' => 'סיסמתכם שונתה בהצלחה!',
+'changepassword-throttled' => 'ביצעתם לאחרונה ניסיונות רבים מדי להיכנס לחשבון זה.
+אנא המתינו $1 לפני שתנסו שוב.',
'resetpass_forbidden' => 'לא ניתן לשנות סיסמאות.',
'resetpass-no-info' => 'יש להיכנס לחשבון כדי לגשת לדף זה באופן ישיר.',
'resetpass-submit-loggedin' => 'שינוי סיסמה',
'changeemail-password' => 'סיסמה ב{{grammar:תחילית|{{SITENAME}}}}:',
'changeemail-submit' => 'שינוי כתובת הדוא"ל',
'changeemail-cancel' => 'ביטול',
+'changeemail-throttled' => 'ביצעתם ניסיונות רבים מדי להיכנס לחשבון זה.
+אנא המתינו $1 לפני שתנסו שוב.',
# Special:ResetTokens
'resettokens' => 'איפוס אסימונים',
'invalid-content-data' => 'מידע שגוי על התוכן',
'content-not-allowed-here' => 'תוכן מסוג "$1" אינו מותר בדף [[$2]]',
'editwarning-warning' => 'עזיבת דף זה עשויה לגרום לאובדן כל השינויים שביצעתם.
-אם אתם מחוברים לחשבון, תוכלו לבטל אזהרה זו בחלק "עריכה" שבהעדפות שלכם.',
+אם אתם מחוברים לחשבון, תוכלו לבטל אזהרה זו בחלק "{{int:prefs-editing}}" שבהעדפות שלכם.',
'editpage-notsupportedcontentformat-title' => 'סוג התוכן אינו נתמך',
'editpage-notsupportedcontentformat-text' => 'תוכן מסוג $1 אינו נתמך על־ידי מודל התוכן $2.',
'showhideselectedversions' => 'הצגת/הסתרת הגרסאות שנבחרו',
'editundo' => 'ביטול',
'diff-empty' => '(אין הבדלים)',
+'diff-multi-sameuser' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} ממשתמש אחד אינן מוצגות',
+'diff-multi-otherusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} {{PLURAL:$2|ממשתמש אחד|מ-$2 משתמשים}} אינן מוצגות)',
'diff-multi-manyusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של יותר {{PLURAL:$2|ממשתמש אחד|מ־$2 משתמשים}} {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})',
'difference-missing-revision' => '{{PLURAL:$2|גרסה אחת|$2 גרסאות}} של ההבדל הזה בין שתי גרסאות ($1) {{PLURAL:$2|לא נמצאה|לא נמצאו}}.
'shown-title' => 'הצגת {{PLURAL:$1|תוצאה אחת|$1 תוצאות}} בדף',
'viewprevnext' => 'צפייה ב: ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''קיים דף בשם \"[[:\$1]]\" באתר זה.'''",
-'searchmenu-new' => "'''יצירת הדף \"[[:\$1]]\" באתר זה.'''",
+'searchmenu-new' => "<strong>'''יצירת הדף \"[[:\$1]]\" באתר זה.'''</strong>
+{{PLURAL:\$2|0=|ראו גם את הדף שנמצא בחיפוש שלכם.|ראו גם את תוצאות החיפוש שלכם.}}",
'searchprofile-articles' => 'דפי תוכן',
'searchprofile-project' => 'עזרה ודפי המיזם',
'searchprofile-images' => 'מולטימדיה',
'watchmethod-list' => 'בודק את העריכות האחרונות בדפים שברשימת המעקב',
'watchlistcontains' => 'רשימת המעקב כוללת {{PLURAL:$1|דף אחד|$1 דפים}}.',
'iteminvalidname' => 'בעיה עם $1, שם שגוי…',
+'wlnote2' => 'להלן השינויים האחרונים ב{{PLURAL:$1|שעה האחרונה|-<strong> $1 </strong> שעות האחרונות}}, מ-$2, $3.',
'wlshowlast' => '(הצגת $1 שעות אחרונות | $2 ימים אחרונים | $3)',
'watchlist-options' => 'אפשרויות ברשימת המעקב',
'allmessages-prefix' => 'סינון לפי קידומת:',
'allmessages-language' => 'שפה:',
'allmessages-filter-submit' => 'הצגה',
+'allmessages-filter-translate' => 'תרגום',
# Thumbnails
'thumbnail-more' => 'הגדלה',
'category-empty' => "''Þessi flokkur inniheldur engar síður eða margmiðlunarefni.''",
'hidden-categories' => '{{PLURAL:$1|Falinn flokkur|Faldir flokkar}}',
'hidden-category-category' => 'Faldir flokkar',
-'category-subcat-count' => '{{PLURAL:$2|Þessi flokkur hefur einungis eftirfarandi undirflokk.|Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}, af alls $2.}}',
-'category-subcat-count-limited' => 'Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}.',
+'category-subcat-count' => 'Þessi flokkur hefur eftirfarandi $1 {{PLURAL:$1|undirflokk|undirflokka}}, af alls $2.',
+'category-subcat-count-limited' => 'Þessi flokkur hefur eftirfarandi $1 {{PLURAL:$1|undirflokk|undirflokka}}.',
'category-article-count' => 'Þessi flokkur inniheldur {{PLURAL:$1|$1 síðu|$1 síður}}, af alls {{PLURAL:$2|$2}}.',
-'category-article-count-limited' => 'Eftirfarandi {{PLURAL:$1|síða er|$1 síður eru}} í þessum flokki.',
+'category-article-count-limited' => 'Eftirfarandi $1 {{PLURAL:$1|síða er|síður eru}} í þessum flokki.',
'category-file-count' => 'Þessi flokkur inniheldur {{PLURAL:$1|$1 skrá|$1 skrár}}, af alls {{PLURAL:$2|$2}}.',
-'category-file-count-limited' => 'Eftirfarandi {{PLURAL:$1|skrá er|$1 skrár eru}} í þessum flokki.',
+'category-file-count-limited' => 'Eftirfarandi $1 {{PLURAL:$1|skrá er|skrár eru}} í þessum flokki.',
'listingcontinuesabbrev' => 'frh.',
'index-category' => 'Raðaðar skrár',
'noindex-category' => 'Óraðaðar skrár',
'deletethispage' => 'Eyða þessari síðu',
'undeletethispage' => 'Endurvekja þessa síðu',
'undelete_short' => 'Endurvekja {{PLURAL:$1|$1 breytingu|$1 breytingar}}',
-'viewdeleted_short' => 'Skoða {{PLURAL:$1|eina eydda breytingu|$1 eyddar breytingar}}',
+'viewdeleted_short' => 'Skoða $1 {{PLURAL:$1|eydda breytingu|eyddar breytingar}}',
'protect' => 'Vernda',
'protect_change' => 'breyta',
'protectthispage' => 'Vernda þessa síðu',
'redirectedfrom' => '(Tilvísað frá $1)',
'redirectpagesub' => 'Tilvísunarsíða',
'lastmodifiedat' => 'Þessari síðu var síðast breytt $1 klukkan $2.',
-'viewcount' => 'Þessi síða hefur verið skoðuð {{PLURAL:$1|einu sinni|$1 sinnum}}.',
+'viewcount' => 'Þessi síða hefur verið skoðuð $1 {{PLURAL:$1|sinni|sinnum}}.',
'protectedpage' => 'Vernduð síða',
'jumpto' => 'Stökkva á:',
'jumptonavigation' => 'flakk',
Vinsamlegast skráðu þig inn á ný þegar þú hefur móttekið það.',
'blocked-mailpassword' => 'Þér er ekki heimilt að gera breytingar frá þessu netfangi og því getur þú ekki fengið nýtt lykilorð í pósti. Þetta er gert til þess að koma í veg fyrir skemmdarverk.',
'eauthentsent' => 'Staðfestingarpóstur hefur verið sendur á uppgefið netfang. Þú verður að fylgja leiðbeiningunum í póstinum til þess að virkja netfangið og staðfesta að það sé örugglega þitt.',
-'throttled-mailpassword' => 'Tölvupóstur til að endursetja lykilorðið hefur þegar verið sent, innan við {{PLURAL:$1|síðasta klukkutímans|$1 síðustu klukkutímanna}}.
-Til að koma í veg fyrir misnotkun, er aðeins einn tölvupóstur sendur {{PLURAL:$1|hvern klukkutíma|hverja $1 klukkutíma}}.',
+'throttled-mailpassword' => 'Tölvupóstur til að endursetja lykilorðið hefur þegar verið sent, innan við $1 {{PLURAL:$1|síðasta klukkutímans|síðustu klukkutímanna}}.
+Til að koma í veg fyrir misnotkun, er aðeins einn tölvupóstur sendur {{PLURAL:$1|hvern $1 klukkutíma|hverja $1 klukkutíma}}.',
'mailerror' => 'Upp kom villa við sendingu tölvupósts: $1',
'acct_creation_throttle_hit' => 'Því miður, hafa verið búnir til {{PLURAL:$1|$1 nýr aðgangur|$1 nýjir aðgangar}} í dag sem er hámarksfjöldi nýskráninga á einum degi.
Þú getur því miður ekki búið til nýjan aðgang frá þessari IP-tölu að svo stöddu.',
'templatesusedsection' => 'Snið {{PLURAL:$1|notað|notuð}} í þessum hluta:',
'template-protected' => '(vernduð)',
'template-semiprotected' => '(hálfvernduð)',
-'hiddencategories' => 'Þessi síða er meðlimur í {{PLURAL:$1|1 földum flokki|$1 földum flokkum}}:',
+'hiddencategories' => 'Þessi síða er meðlimur í $1 {{PLURAL:$1|földum flokki|földum flokkum}}:',
'nocreatetext' => '{{SITENAME}} hefur takmarkað eiginleikann að gera nýjar síður.
Þú getur farið til baka og breytt núverandi síðum, eða [[Special:UserLogin|skráð þið inn eða búið til aðgang]].',
'nocreate-loggedin' => 'Þú hefur ekki leyfi til að skapa nýjar síður.',
'nolinkstoimage' => 'Engar síður tengja í þessa skrá.',
'morelinkstoimage' => 'Skoða [[Special:WhatLinksHere/$1|fleiri myndatengla]] á þessa skrá.',
'linkstoimage-redirect' => '$1 (tilvísun) $2',
-'duplicatesoffile' => 'Eftirfarandi {{PLURAL:$1|skrá er afrit|$1 skrár eru afrit}} af þessari skrá ([[Special:FileDuplicateSearch/$2|Frekari upplýsingar]]):',
+'duplicatesoffile' => 'Eftirfarandi $2 {{PLURAL:$1|skrá er afrit|skrár eru afrit}} af þessari skrá ([[Special:FileDuplicateSearch/$2|Frekari upplýsingar]]):',
'sharedupload' => 'Skrá þessi er af $1, og deilt meðal annarra verkefna og nýtist því þar.',
'sharedupload-desc-there' => 'Skrá þessi er af $1, og deilt meðal annarra verkefna og nýtist því þar.
Gjörðu svo vel og sjáðu [$2 skráarsíðuna þar] fyrir fleiri upplýsingar.',
'statistics-views-peredit' => 'Uppflettingar á hverja breytingu (meðaltal)',
'statistics-users' => 'Skráðir [[Special:ListUsers|notendur]]',
'statistics-users-active' => 'Virkir notendur',
-'statistics-users-active-desc' => 'Notendur sem hafa framkvæmt aðgerð {{PLURAL:$1|síðastliðin dag|síðastliðna $1 daga}}',
+'statistics-users-active-desc' => 'Notendur sem hafa framkvæmt aðgerð {{PLURAL:$1|síðusta $1 dag|síðustu $1 daga}}',
'statistics-mostpopular' => 'Mest skoðuðu síður',
'pageswithprop' => 'Síður með eiginleika',
'notargettext' => 'Villa: Engin síða eða notandi tilgreind til að nota þennan möguleika á.',
'nopagetitle' => 'Síðan er ekki til',
'nopagetext' => 'Síðan sem á að færa frá er ekki til.',
-'pager-newer-n' => '{{PLURAL:$1|nýrri 1|nýrri $1}}',
+'pager-newer-n' => '{{PLURAL:$1|nýrri}} $1',
'pager-older-n' => '{{PLURAL:$1|1 eldri|$1 eldri}}',
'suppress' => 'Yfirsýn',
'querypage-disabled' => 'Þessi kerfisíða er óvirk til að minnka ekki afköst vefþjónsins.',
# Special:ActiveUsers
'activeusers' => 'Virkir notendur',
'activeusers-intro' => 'Þetta er listi yfir notendur sem hafa verið virkir {{PLURAL:$1|síðasta|síðustu}} $1 {{PLURAL:$1|dag|daga}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
+'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðasta $3 degi|síðustu $3 dögum}}',
'activeusers-from' => 'Sýna notendur sem byrja á:',
'activeusers-hidebots' => 'Fela vélmenni',
'activeusers-hidesysops' => 'Fela möppudýr',
'undeletepage' => 'Skoða og endurvekja eyddar síður',
'undeletepagetitle' => "'''Eftirfarandi er samansafn af eyddum breytingum á [[:$1|$1]]'''.",
'viewdeletedpage' => 'Skoða eyddar síður',
-'undeletepagetext' => 'Eftirfarandi {{PLURAL:$1|síðu hefur verið eytt en hún er þó enn í gagnagrunninum og getur verið endurvakin|$1 síðum hefur verið eytt en eru þó enn í gagnagrunninum og geta verið endurvaknar}}.
+'undeletepagetext' => 'Eftirfarandi $1 {{PLURAL:$1|síðu hefur verið eytt en hún er þó enn í gagnagrunninum og getur verið endurvakin|síðum hefur verið eytt en eru þó enn í gagnagrunninum og geta verið endurvaknar}}.
Gagnagrunnurinn kann að vera tæmdur reglulega.',
'undelete-fieldset-title' => 'Endurvekja breytingar',
'undeleteextrahelp' => "Til þess að endurvekja alla breytingarskrá síðunnar, skildu öll box eftir óhökuð og ýttu á '''''{{int:undeletebtn}}'''''.
'movelogpage' => 'Flutningaskrá',
'movelogpagetext' => 'Þetta er listi yfir síður sem nýlega hafa verið færðar.',
'movesubpage' => '{{PLURAL:$1|Undirsíða|Undirsíður}}',
-'movesubpagetext' => 'Þessi síða hefur {{PLURAL:$1|eina undirsíðu|$1 undirsíður}} sem {{PLURAL:$1|er sýnd|eru sýndar}} hér fyrir neðan.',
+'movesubpagetext' => 'Þessi síða hefur $1 {{PLURAL:$1|undirsíðu|undirsíður}} sem {{PLURAL:$1|er sýnd|eru sýndar}} hér fyrir neðan.',
'movenosubpage' => 'Þessi síða hefur engar undirsíður.',
'movereason' => 'Ástæða:',
'revertmove' => 'taka til baka',
'file-info-gif-looped' => 'síendurtekin hreyfimynd',
'file-info-gif-frames' => '$1 {{PLURAL:$1|rammi|rammar}}',
'file-info-png-looped' => 'síendurtekin hreyfimynd',
-'file-info-png-repeat' => 'spilað {{PLURAL:$1|einu sinni|$1 sinnum}}',
+'file-info-png-repeat' => 'spilað $1 {{PLURAL:$1|sinni|sinnum}}',
'file-info-png-frames' => '$1 {{PLURAL:$1|rammi|rammar}}',
'file-no-thumb-animation' => "'''Athugið: Vegna tæknilegra takmarkanna birtast smámyndir af þessari skrá aðeins sem kyrrmyndir.'''",
'file-no-thumb-animation-gif' => "'''Athugið:Vegna tæknilegra takmarkanna munu smámyndir af GIF-myndum í hárri upplausn eins og þessari ekki birtast sem hreyfimyndir.'''",
'sp-newimages-showfrom' => 'Leita af nýjum skráum frá $2, $1',
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds' => '{{PLURAL:$1|einni sekúndu|$1 sekúndum}}',
-'minutes' => '{{PLURAL:$1|einni mínútu|$1 mínútum}}',
-'hours' => '{{PLURAL:$1|einum klukkutíma|$1 klukkutímum}}',
-'days' => '{{PLURAL:$1|einum degi|$1 dögum}}',
+'seconds' => '$1 {{PLURAL:$1|sekúndu|sekúndum}}',
+'minutes' => '$1 {{PLURAL:$1|mínútu|mínútum}}',
+'hours' => '$1 {{PLURAL:$1|klukkutíma|klukkutímum}}',
+'days' => '$1 {{PLURAL:$1|degi|dögum}}',
'weeks' => '{{PLURAL:$1|$1 vika|$1 vikur}}',
'months' => '{{PLURAL:$1|$1 mánuði|$1 mánuðum}}',
'years' => '{{PLURAL:$1|$1 ári|$1 árum}}',
'api-error-badaccess-groups' => 'Þú hefur ekki leyfi til að hlaða inn skrám.',
'api-error-badtoken' => 'Innri villa: Skemmdur tóki.',
'api-error-copyuploaddisabled' => 'Ekki er hægt að hlaða upp með vefslóð á þessum vefþjón.',
-'api-error-duplicate' => 'Það {{PLURAL:$1|er [$2 önnur skrá]|eru[$2 aðrar skrár]}} þegar til á vefsvæðinu sem hafa sama innihald.',
+'api-error-duplicate' => 'Það {{PLURAL:$1|er [$2 önnur skrá]|eru [$2 aðrar skrár]}} þegar til á vefsvæðinu sem hafa sama innihald.',
'api-error-duplicate-archive' => 'Það {{PLURAL:$1|var [$2 önnur skrá]|voru [$2 aðrar skrár]}} þegar á síðunni með sama innihald, en {{PLURAL:$1|henni|þeim}} var eytt.',
'api-error-duplicate-archive-popup-title' => 'Eins {{PLURAL:$1|skrá|skrár}} sem {{PLURAL:$1|hefur|hafa}} þegar verið eytt.',
'api-error-duplicate-popup-title' => '{{PLURAL:$1|Afrituð skrá|Afritaðar skrár}}',
'invalid-content-data' => 'Dati contenuti non validi',
'content-not-allowed-here' => 'Contenuto in "$1" non consentito nella pagine [[$2]]',
'editwarning-warning' => 'Lasciare questa pagina potrebbe causare la perdita di tutte le modifiche fatte.
-Se hai effettuato l\'accesso, puoi disattivare questo avviso nella sezione "Casella di modifica" delle tue preferenze.',
+Se hai effettuato l\'accesso, puoi disattivare questo avviso nella sezione "{{int:prefs-editing}}" delle tue preferenze.',
'editpage-notsupportedcontentformat-title' => 'Formato contenuto non supportato',
'editpage-notsupportedcontentformat-text' => 'Il formato del contenuto $1 non è supportato dal modello di contenuto $2.',
Controlla le differenze mostrate sotto fra le due versioni per essere certo che il contenuto corrisponda a quanto desiderato, e quindi salvare le modifiche per completare la procedura di annullamento.',
'undo-failure' => 'Impossibile annullare la modifica a causa di un conflitto con modifiche intermedie.',
'undo-norev' => 'La modifica non può essere annullata perché non esiste o è stata cancellata.',
+'undo-nochange' => 'Sembra che la modifica sia già stata annullata.',
'undo-summary' => 'Annullata la modifica $1 di [[Special:Contributions/$2|$2]] ([[User talk:$2|discussione]])',
'undo-summary-username-hidden' => 'Annullata la modifica $1 di un utente nascosto',
'showhideselectedversions' => 'Mostra/nascondi versioni selezionate',
'editundo' => 'annulla',
'diff-empty' => '(Nessuna differenza)',
-'diff-multi-sameuser' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di uno stesso utente non sono mostrate )',
-'diff-multi-otherusers' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di {{PLURAL:$2|un altro utente|$2 utenti}} non mostrate)',
-'diff-multi-manyusers' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di oltre $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrata|mostrate}})',
+'diff-multi-sameuser' => '({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di uno stesso utente non 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}})',
'difference-missing-revision' => '{{PLURAL:$2|Una versione|$2 versioni}} di questa differenza ($1) {{PLURAL:$2|non è stata trovata|non sono state trovate}}.
Questo si verifica solitamente seguendo un collegamento obsoleto di un diff a una pagina cancellata.
'invalid-content-data' => '本文データが無効です',
'content-not-allowed-here' => 'ページ [[$2]] では、「$1」コンテンツは許可されていません',
'editwarning-warning' => 'このページを離れると、あなたが行なった変更がすべて失われてしまうかもしれません。
-ログインしている場合、個人設定の「編集」タブでこの警告を表示しないようにすることができます。',
+ログインしている場合、個人設定の「{{int:prefs-editing}}」タブでこの警告を表示しないようにすることができます。',
'editpage-notsupportedcontentformat-title' => '対応していないコンテンツ形式',
'editpage-notsupportedcontentformat-text' => 'コンテンツ モデル $2 は、コンテンツ形式 $1 に対応していません。',
'contributions-title' => '$1 de iştırakê karberi',
'mycontris' => 'İştıraqi',
'contribsub2' => 'Serba $1 ($2)',
-'uctop' => '(ser)',
+'uctop' => '(rocane)',
'month' => 'Asme ra (u ravêr):',
'year' => 'Serre ra (u ravêr):',
'edit-gone-missing' => 'Бетті жаңарту мүмкін емес.
Мүмкін, бұл бет жойылған.',
'edit-conflict' => 'Өңдемелер қақтығысы.',
-'postedit-confirmation' => 'Сіздің өңдемеңіз сақталды.',
+'postedit-confirmation' => 'Өңдемеңіз сақталды.',
'edit-already-exists' => 'Жаңа бет жасау мүмкін емес.
Ол әлдеқашан бар.',
'defaultmessagetext' => 'Әдепкі мәтіні',
'showhideselectedversions' => 'Бөлектенген нұсқаларды көрсет/жасыр',
'editundo' => 'жоққа шығару',
'diff-empty' => '(айырмашылығы жоқ)',
+'difference-missing-revision' => 'Бұл ($1) {{PLURAL:$2|нұсқа|$2 нұсқалар}} айырмашылығы табылмады.
+
+
+Бұл әлте жойылған беттің нұсқалар айырмашылығының сілтемесі.
+Егжей-тегжейін [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} жою журналынан] таба аласыз.',
# Search results
'searchresults' => 'Іздеу нәтижелері',
'listfiles_size' => 'Өлшемі',
'listfiles_description' => 'Сипаттамасы',
'listfiles_count' => 'Нұсқалары',
+'listfiles-show-all' => 'Суреттердің ескі нұсқаларын да қамту',
'listfiles-latestversion' => 'Соңғы нұсқасы',
'listfiles-latestversion-yes' => 'Иә',
'listfiles-latestversion-no' => 'Жоқ',
'invalid-content-data' => '잘못된 내용 데이터입니다',
'content-not-allowed-here' => '"$1" 내용은 [[$2]] 문서예 허용하지 않습니다',
'editwarning-warning' => '이 페이지에서 벗어나면 저장하지 않은 바뀜이 모두 사라집니다.
-로그인을 했다면, 환경 설정의 "편집 상자"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.',
+로그인을 했다면, 환경 설정의 "{{int:편집 상자}}"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.',
'editpage-notsupportedcontentformat-title' => '지원하지 않는 컨텐츠 형식',
'editpage-notsupportedcontentformat-text' => '컨텐츠 모델 $2 에서는 컨텐츠형식 $1을 지원하지 않습니다.',
'showhideselectedversions' => '선택한 판을 보이기/숨기기',
'editundo' => '편집 취소',
'diff-empty' => '(차이 없음)',
+'diff-multi-sameuser' => '(같은 사용자에 의한 {{PLURAL:$1|하나의 중간 편집|$1개의 중간 편집}}이 숨겨짐)',
+'diff-multi-otherusers' => '({{PLURAL:$2|한 명의 사용자|$2명의 사용자}}에 의한 {{PLURAL:$1|$1개의 중간 편집}}이 숨겨짐)',
'diff-multi-manyusers' => '({{PLURAL:$2|한 사용자의|사용자 $2명 이상의}} {{PLURAL:$1|중간의 편집 $1개}} 숨겨짐)',
'difference-missing-revision' => '문서 비교에서 {{PLURAL:$2|하나|$2개}}의 판($1)을 찾을 수 {{PLURAL:$2|없습니다}}.
'shown-title' => '쪽마다 {{PLURAL:$1|결과}} $1개씩 보기',
'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) 보기',
'searchmenu-exists' => "'''이 위키에 \"[[:\$1]]\"의 이름을 가진 문서가 있습니다.'''",
-'searchmenu-new' => "'''이 위키에 \"[[:\$1]]\" 문서를 만드세요!'''",
+'searchmenu-new' => '<strong>이 위키에 "[[:$1]]" 문서를 만드세요!</strong>
+{{PLURAL:$2|0=|검색으로 찾은 문서들을 참조하세요.}}',
'searchprofile-articles' => '본문',
'searchprofile-project' => '도움말 및 프로젝트 문서',
'searchprofile-images' => '멀티미디어',
임시 폴더가 존재하지 않습니다.',
'import-parse-failure' => 'XML 문서 분석 실패',
'import-noarticle' => '가져올 문서가 없습니다!',
-'import-nonewrevisions' => '이전에 이미 모든 판을 가져왔습니다.',
+'import-nonewrevisions' => '가져온 판 없음(모든 판이 이미 존재하거나 오류로 인해 건너뛰었을 수도 있습니다.)',
'xml-error-string' => '$3단 $2줄 (바이트 $4)에서 $1: $5',
'import-upload' => 'XML 데이터 올리기',
'import-token-mismatch' => '세션 데이터가 손실되었습니다.
'import-error-special' => '"$1" 문서는 특수 문서에 속해 있기 때문에 가져오지 않습니다.',
'import-error-invalid' => '"$1" 문서는 제목이 잘못되었기 때문에 가져오지 않습니다.',
'import-error-unserialize' => '"$1" 문서의 $2 판이 일렬적이지 않습니다. $3 내용 모델을 사용하여 $4 형식으로 일렬화되도록 판을 보고했습니다.',
+'import-error-bad-location' => '$3 내용 모델을 사용하는 $2 판을 이 위키의 "$1"에 저장할 수 없습니다. 모델을 문서에서 지원하지 않습니다.',
'import-options-wrong' => '잘못된 {{PLURAL:$2|선택 사항}}: <nowiki>$1</nowiki>',
'import-rootpage-invalid' => '주어진 루트 문서는 잘못된 제목입니다.',
'import-rootpage-nosubpage' => '루트 문서의 "$1" 이름공간은 하위 문서를 허용하지 않습니다.',
'expand_templates_preview' => '미리 보기',
# Unknown messages
+'createaccount-hook-aborted' => '$1',
'uploadinvalidxml' => '업로드된 파일의 XML의 구문을 분석할 수 없습니다.',
);
'undelete_short' => 'Traer atrás $1 {{PLURAL:$1|trocamientos|trocamientos}}',
'viewdeleted_short' => 'Ver {{PLURAL:$1|un trocamiento efassado|$1 trocamientos efassados}}',
'protect' => 'Guadrar',
-'protect_change' => 'trocar el guardadijo',
+'protect_change' => 'trocar',
'protectthispage' => 'Guardar esta hoja',
'unprotect' => 'Trocar guardadijo',
'unprotectthispage' => 'Trocar el guardadijo desta hoja',
'revdelete-radio-set' => 'Eskondido',
'revdelete-radio-unset' => 'Visible',
'revdelete-log' => 'Razon:',
-'revdel-restore' => 'troca la vizibilitá',
+'revdel-restore' => 'trocar la vizibilitá',
'pagehist' => 'La storia de la hoja',
'revdelete-otherreason' => 'Otro razon/razon adisiyonal',
'revdelete-reasonotherlist' => 'Otra razón',
'searchprofile-advanced-tooltip' => 'Buxcar en espacios de nombres partikolares',
'search-result-size' => '$1 ({{PLURAL:$2|1 biervo|$2 biervos}})',
'search-result-category-size' => '{{PLURAL:$1|1 miembro|$1 miembros}} ({{PLURAL:$2|1 basho-kateggoria|$2 basho-kateggoria}}, {{PLURAL:$3|1 dossia|$3 dossias}})',
-'search-redirect' => '(direksión desde $1)',
+'search-redirect' => '(redireksión de la hoja $1)',
'search-section' => '(kapítolo $1)',
'search-suggest' => 'Quijites dezir: $1',
'search-interwiki-caption' => 'Proyectos hermanos',
'recentchangeslinked-feed' => 'Trocamientos conectados',
'recentchangeslinked-toolbox' => 'Trocamientos atados',
'recentchangeslinked-title' => 'Los trocamientos relacionados con "$1"',
-'recentchangeslinked-summary' => "Esto es la lista de los trocamientos dalcavo de las hojas que relatan a una hoja particòlar (o de los miembros de la kategoría particòlar).
-Las hojas en tu [[Special:Watchlist|lista de akavidamiento]] son '''reforçadas'''.",
+'recentchangeslinked-summary' => "Esto es una lista de trocamientos dalcavo en las hojas atadas de una hoja partikolara (u en los miembros de una kategoría partikolara).
+Las hojas en tu [[Special:Watchlist|lista de acavidamiento]] son '''reforçadas'''.",
'recentchangeslinked-page' => 'Nombre de la hoja',
'recentchangeslinked-to' => 'Amostra los trocamientos freskos en lugar de la hoja indicada',
'filehist-filesize' => 'El boy de la dosya',
'filehist-comment' => 'Comentario',
'filehist-missing' => 'No se topa el archivo',
-'imagelinks' => 'El uso del dosya',
+'imagelinks' => 'Usos de la dosya',
'linkstoimage' => '{{PLURAL:$1|La hoja venidera da link|Las hojas venideras dan link}} a esta dosya:',
'nolinkstoimage' => 'No ay hojas con atamientos a esta dosya.',
'sharedupload' => 'Este arxivo es de $1 i puede ser usado por otros proyectos.',
'tooltip-ca-protect' => 'Guardar esta hoja',
'tooltip-ca-delete' => 'Efassar esta hoja',
'tooltip-ca-move' => 'Taxirea (renombra) esta hoja',
-'tooltip-ca-watch' => 'Ajustar esta hoja a tu lista de akavidamientos',
+'tooltip-ca-watch' => 'Ajusta esta hoja a tu lista de acavidamientos',
'tooltip-ca-unwatch' => 'Quita esta hoja de tu lista de escojidos',
'tooltip-search' => 'Buxca en {{SITENAME}}',
'tooltip-search-go' => 'Ir a la hoja con este nombre egzakto, si egziste.',
'tooltip-n-randompage' => 'Carga una hoja por azardo',
'tooltip-n-help' => 'Ambézate y topa ayudo',
'tooltip-t-whatlinkshere' => 'Una lista de todas las hojas del viki que tienen atamientos a esta hoja',
-'tooltip-t-recentchangeslinked' => 'Los trocamientos dalcavo de las hojas atadas a la ésta',
+'tooltip-t-recentchangeslinked' => 'Los trocamientos dalcavo en las hojas atadas a la ésta',
'tooltip-feed-rss' => 'Sindicación RSS de esta hoja',
-'tooltip-feed-atom' => "Fuente de Atom d'esta hoja",
+'tooltip-feed-atom' => 'Canal Atomo parâ esta hoja',
'tooltip-t-contributions' => 'Ver la lista de ajustamientos de este usuario',
'tooltip-t-emailuser' => 'A este usuario, mándale una letra electrόnica (ímey)',
'tooltip-t-upload' => 'Suve dosyas',
'tooltip-watch' => 'Ajusta esta hoja a tu lista de escojidas',
'tooltip-rollback' => '«Hazer aboltar» haze aboltar todos los trocamientos del usador dalcavo, sólo en klikando una vez.',
'tooltip-undo' => '«Des-hazer» abolta este trocamiento y lo avre en el modo de previsteo. Permete ajustar una razón en el somario.',
-'tooltip-summary' => 'Entrar un somaryo kurto',
+'tooltip-summary' => 'Entrar un somario curto',
# Attribution
'anonymous' => '{{PLURAL:$1|Uzuario anonimo|Uzuarios anonimos}} de {{SITENAME}}',
'invalid-content-data' => 'Donnéeë vum Inhalt sinn net valabel',
'content-not-allowed-here' => '"$1"-Inhalt ass op der Säit [[$2]] net erlaabt',
'editwarning-warning' => 'Wann Dir dës Säit verloosst kann dat dozou féieren datt Dir all Ännerungen, déi Dir gemaach hutt, verléiert.
-Wann Dir ageloggt sidd, kënnt Dir dës Warnung an der Sektioun "Änneren" vun Ären Astellungen ausschalten.',
+Wann Dir ageloggt sidd, kënnt Dir dës Warnung an der Sektioun "{{int:prefs-editing}}" vun Ären Astellungen ausschalten.',
'editpage-notsupportedcontentformat-title' => 'Format vum Inhalt gëtt net ënnerstëtzt',
'editpage-notsupportedcontentformat-text' => 'De Format vum Inhalt $1 gëtt net vum Modell vum Inhalt $2 ënnerstëtzt.',
'undo-success' => "D'Ännerung gëtt réckgängeg gemaach. Iwwerpréift w.e.g. de Verglach ënnendrënner fir nozekuckeen ob et sou richteg ass, duerno späichert w.e.g d'Ännerungen of, fir dës Aktioun ofzeschléissen.",
'undo-failure' => "D'Ännerung konnt net réckgängeg gemaach ginn, wëll de betraffenen Abschnitt an der Tëschenzäit geännert gouf.",
'undo-norev' => "D'Ännerung kann net zréckgesat ginn, well et se net gëtt oder well se scho geläscht ass.",
+'undo-nochange' => "D'Ännerung gouf anscheinend schonn zeréckgesat.",
'undo-summary' => 'Ännerung $1 vu(n) [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussioun]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]]) annulléieren.',
'undo-summary-username-hidden' => 'Versioun $1 vun engem verstoppte Benotzer zrécksetzen',
'disclaimers' => 'منكرون',
'disclaimerpage' => 'پروجه:منكر بيئن كاروريا',
'edithelp' => 'هومياری سی ويرايشت',
-'helppage' => 'هومياری:محتوا',
+'helppage' => 'هومياری:مینونه',
'mainpage' => 'سرآسونه',
'mainpage-description' => 'سرآسونه',
'policy-url' => 'پروجه:خط و مش',
'watchnologintext' => 'شما سی آلشت دئن سیل برگتو با [[ویجه:وامین اومائن کارور|وامین اومائه]]',
'watch' => 'سيل كردن',
'unwatch' => 'ديه نبيه',
+'notanarticle' => 'مینونه هیچ بلگه ای نئ',
'watchlist-details' => '{{جمی:$1|$1 بلگه|$1 بلگیا}} د سیل برگتو هیش بلگه قسه کردن نی .',
+'wlheader-enotif' => 'وارسیاری ایمیل فعال بیه.',
'wlshowlast' => 'آخرین$1 ساعتیا $2و روزیا $3 نشو بیئه',
'watchlist-options' => 'گزینیا سیل برگ',
+'enotif_mailer' => '{{نوم سیلجا}} وارسیاری ایمیل زننه',
'enotif_impersonal_salutation' => '{{نوم سیلجا}} کارور',
# Delete
+'excontent' => 'مینونه :"$1" بی',
+'exbeforeblank' => 'مینونه حالی دمایی:"$1" بی',
'actioncomplete' => 'عملكرد كامل بيه',
'actionfailed' => 'عملكرد شكست حرده',
'dellogpage' => 'لاگ پاك كردن',
'prot_1movedto2' => '[[$1]] د [[$2]] جا وه جا بی',
'protect-default' => 'همه کاروریا اجازه دارن',
'protect-othertime' => 'وخت هنی:',
+'protect-expiry-options' => '1 ساعت:1 ساعت,1 روز:1 روز,1 هفته:1 هفته,2 هفته:2 هفته,1 ما:1 ما,3 ما:3 ما,6 ما:6 ما,1 سال:1 سال,بی حساو:بی حساو',
'restriction-type' => 'دسرسی:',
# Restrictions (nouns)
'block' => 'منع کارور',
'blockip' => 'منع کارور',
'ipbother' => 'وخت هنی:',
-'ipboptions' => '2 ساعتÛ\8cا:2 ساعت,1 رÙ\88:1 رÙ\88,3 رÙ\88زا:3 رÙ\88,1 Ù\87Ù\81تÙ\87:1 Ù\87Ù\81تÙ\87,2 Ù\87Ù\81تÙ\87 Û\8cا:2 Ù\87Ù\81تÙ\87,1 Ù\85ا:1 Ù\85ا,3 Ù\85ا:3 Ù\85Û\8cا,6 Ù\85ا:6 Ù\85اÛ\8cا,1 ساÙ\84:1ساÙ\84,Øد Ù\86ارÙ\87:Øد Ù\86ارÙ\87',
+'ipboptions' => '2 ساعتÛ\8cا:2 ساعت,1 رÙ\88:1 رÙ\88,3 رÙ\88زا:3 رÙ\88,1 Ù\87Ù\81تÙ\87:1 Ù\87Ù\81تÙ\87,2 Ù\87Ù\81تÙ\87 Û\8cا:2 Ù\87Ù\81تÙ\87,1 Ù\85ا:1 Ù\85ا,3 Ù\85ا:3 Ù\85Û\8cا,6 Ù\85ا:6 Ù\85اÛ\8cا,1 ساÙ\84:1ساÙ\84,بÛ\8c ØساÙ\88:بÛ\8c ØساÙ\88',
'ipbhidename' => 'نوم کاروری نه سی ویرایشت یا و نوم گه یا قام کو',
'unblockip' => 'کارور منع نبیه',
'blocklist' => 'كاروريا منع بيه',
# Info page
'pageinfo-language' => 'بلگه مینونه زون',
+'pageinfo-content-model' => 'شلگ مینونه بلگه',
'pageinfo-category-files' => 'شماره جانیایا',
# Patrol log
'newimages-label' => 'نوم جانیا(یا بشقی د وه):',
'sp-newimages-showfrom' => 'جانیایا تازه نه که $2 ، $2 شرو بینه نشو بیه',
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'days' => '{{جمی:$1|1$ روز|$1 روز}}',
+'years' => '{{جمی:$1|$1 سال|$1 سال}}',
+
+# Human-readable timestamps
+'monday-at' => 'دوشمه د $1',
+
# Bad image list
'bad_image_list' => 'دونسمنديانه وه ای شلگ وارد بكيت:
'exif-filesource' => 'سرچشمه جانیا',
'exif-gpstimestamp' => 'وخت جی پی اس (ساعت اتمی)',
'exif-jpegfilecomment' => 'ویر و باور فایل پی ان جی',
+'exif-citycreated' => 'شهری که عسگ دش گرته بیه',
+'exif-citydest' => 'شهر دیار بیه',
'exif-languagecode' => 'زون',
'exif-datetimeexpires' => 'وا نها دش استفاده نبوئه',
'exif-pngfilecomment' => 'ویر و باور فایل جی پی ان جی',
'exif-exposureprogram-1' => 'دسی',
+'exif-lightsource-1' => 'روشنایی روز',
+
+'exif-scenecapturetype-3' => 'چی شو',
+
# Pseudotags used for GPSAltitudeRef
'exif-gpsaltitude-above-sealevel' => '$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا',
'exif-gpsaltitude-below-sealevel' => '$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا',
'exif-gpsdop-good' => 'خو ($1)',
+'exif-iimcategory-ace' => 'هنریا، رهزیشت و زیستگه',
+
# 'all' in various places, this might be different for inflected languages
'watchlistall2' => 'همه شو',
'namespacesall' => 'همه شو',
'imgmultigo' => 'رؤ!',
# Language selector for translatable SVGs
+'img-lang-default' => '(زون پیش زمینه)',
'img-lang-go' => 'رو',
# Table pager
'table_pager_limit_submit' => 'رو',
+# Auto-summaries
+'autosumm-replace' => 'مینونه وا "َ$1" جاگزین بی',
+
# Watchlist editing tools
'watchlisttools-view' => 'آلشتیا مرتوط نه بوینیت',
'watchlisttools-edit' => 'سیل برگ بوینیتو و ویرایشت بکید',
'compare-revision-not-exists' => 'وانئری که شما تی دیار کردیته وجود ناره.',
# New logging system
+'revdelete-content-hid' => 'مینونه قام بیه',
'revdelete-uname-hid' => 'نوم کاروری قام بیه',
+'revdelete-content-unhid' => 'مینونه قام نبیه',
'revdelete-uname-unhid' => 'نوم کاروری قام نبیه',
# Feedback
'api-error-illegal-filename' => 'نوم جانیا اجازه دئه نئ.',
'api-error-mustbeloggedin' => 'شما سی سوارکردن فایلیا با بیایت وامین',
+# Durations
+'duration-days' => '$1{{جمی:$1|روز|روزیا}}',
+'duration-years' => '$1{{جمی:$1| سال|سالیا}}',
+
# Special:ExpandTemplates
'expand_templates_remove_comments' => 'جا وه جا بیئن ویر و باوریا',
'userlogin-resetpassword-link' => 'Hadino ny tenimiafina?',
'helplogin-url' => 'Help:Fidirana',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Fanoroana mikasika ny fidirana]]',
+'userlogin-loggedin' => "Efa tafiditra amin'ny anaran'i {{GENDER:$1|$1}} ianao. Ampiasao ny fôrmiolera eo ambany raha hiditra amin'ny anaran'ny mpikambana hafa.",
'userlogin-createanother' => 'Hamorona kaonty hafa',
'createacct-join' => 'Atsofohy eo ambany ny fampahalalana momba anao.',
'createacct-another-join' => "Atsofohy eo ambany ny fampahalalana vaovaon'ny kaonty",
'passwordsent' => 'Nandefasana tenimiafina vaovao any amin\'ny adiresy imailak\'i "$1".
Azafady midira rehefa voarainao io imailaka io.',
'blocked-mailpassword' => "Voasakana ny adiresy IP-nao, nesorina aminao ny asa ''password recovery'' mba tsy hanararaotra.",
-'eauthentsent' => "
-Efa nandefasana imailaka fanamarinana ilay adiresy nomenao.
-Alohan'ny handraisanao imailaka hafa, dia araho ny torolalana ao anatin'io imailaka io,
-mba hanaporofoana fa anao io kaonty io.",
+'eauthentsent' => "Efa nandefasana imailaka fanamarinana ilay adiresy nomenao.
+Alohan'ny handefasana mailaka hafa any amin'ity kaonty ity dia mila manaraka ny torolalana ianao hahafahana manamarina anao ho tompon'ilay kaonty.",
'throttled-mailpassword' => "Efa nandefasana mailaka famerenana tenimiafiana ianao tanatin'ny {{PLURAL:$1|ora|$1 ora}}.
Mba tsy hisian'ny fanararaotana dia mailaka famerenana tenimiafiana iray ihany no azo ampiasaina isaky ny adin'ny $1{{PLURAL:}}.",
'mailerror' => "Nisy olana tamin'ny fandefasana imailaka: $1",
'acct_creation_throttle_hit' => 'Miala tsiny, efa nanokatra kaonty miisa $1 ianao, ka tsy afaka mamorona hafa intsony.{{PLURAL:}}',
-'emailauthenticated' => "Voamarina tamin'ny $2 $3 ny adiresy imailakao.",
-'emailnotauthenticated' => "Tsy mbola voamarina ny adiresinao. Tsy mbola afaka mandefa hafatra ianao amin'ireto zavatra azo atao manaraka ireto.",
+'emailauthenticated' => "Voamarina tamin'ny $2 tamin'ny $3 ny adiresy mailakao.",
+'emailnotauthenticated' => "Tsy mbola nomarinina ny adiresy mailakao.
+Tsy handefa mailaka izy ho an'ireo asa ireo.",
'noemailprefs' => 'Manomeza adiresy imailaka raha hampiasa ireo fitaovana ireo ianao.',
'emailconfirmlink' => 'Hamarino ny adiresy imailakao',
'invalidemailaddress' => 'Tsy mety io imailaka nalefanao io satria tsy manaraka ny firafitra tokony ho izy.
# Special:PasswordReset
'passwordreset' => 'Famafana ary famerenana ny tenimiafina',
'passwordreset-text-one' => 'Fenoy ity fôrmiolera ity mba hamerenana ny tenimiafinao',
-'passwordreset-text-many' => "Fenoy ny iray amin'ireo saha ireo mba hamerenana ny tenimiafinao{{PLURAL:$1}}",
+'passwordreset-text-many' => '{{PLURAL:$1|Fenoy ny saha mba hahazoanao tenimiafina vonjimaika.}}',
'passwordreset-legend' => 'Famafana ary famerenana ny tenimiafina',
'passwordreset-disabled' => "Tsy nalefa ny fanovana tenimiafina adino eto amin'ity wiki ity.",
'passwordreset-emaildisabled' => "Tsy avela ny fampiasana mailaka eto amin'ity wiki ity.",
'invalid-content-data' => "Data anaty votoatiny tsy miady amin'ny fepetra",
'content-not-allowed-here' => "Votoatiny ''$1'' voarara eo amin'ny pejy [[$2]]",
'editwarning-warning' => "Mety hahavery ny fanovana nataonao ny fialanao amin'ity pejy ity.
-Raha tafiditra ianao dia azonao esorina ity fampitandremana ity ao amin'ny fizarana \"Fanovàna\" ao amin'ny safidinao",
+Raha tafiditra ianao dia azonao esorina ity fampitandremana ity ao amin'ny fizarana \"{{int:prefs-editing}}\" ao amin'ny safidinao.",
# Content models
'content-model-wikitext' => 'wiki-soratra',
'undo-success' => 'Ho voafafa io fanovana io. Marino tsara ny fanovana eo ambany, ary tehirizo rehefa vita.',
'undo-failure' => "Tsy afaka esorina io fanovàna io : mety tsy miraikitra amin'ny fanovàna misy eo ampivoaniny ra esorina",
'undo-norev' => 'Tsy afaka nesorina ilay fanovàna satria tsy misy na efa voafafa izy.',
+'undo-nochange' => 'Hoatry ny efa nofoanana ilay fanovana.',
'undo-summary' => "Niala ny fanovàna $1 nataon'i [[Special:Contributions/$2|$2]] ([[User talk:$2|resaho]])",
'undo-summary-username-hidden' => 'Namafa ny famerenana $1 nataom-pikambana afenina',
Mbola afaka jeren'ireo mpandrindran'i {{SITENAME}} foana ny votoatiny voafina ary azony atao ho hitan'ny vahoaka indray ilay izy amin'ny alalan'ity pejy fanaovan-tsafidy ity, raha tsy misy fepetra apetraka.",
'revdelete-confirm' => 'Amafiso eto ny hevitrao raha hanao io ianao, raha azonao sary an-tsaina ny mety ho vokany, ary raha araka ny [[{{MediaWiki:Policy-url}}|fepetra mihatra]] ny zavatra ataonao.',
'revdelete-suppress-text' => "Ny famafàna pejy dia ampiasaina rehefa :
-* Misy information tsy sarababem-bahoaka tsy metimety
-*: ''Misy adiresy nomeraona antso an-tariby, nomeraona sécurité sociale, sns.''",
+* Fampahalalana mampiely lainga
+* Misy fampahalalana tsy sarababem-bahoaka tsy metimety
+*: ''Adiresy onenana, laharana antso an-tariby, sns.''",
'revdelete-legend' => "Ampetraho ny fepetra momban'ny fahitana :",
-'revdelete-hide-text' => "Asitriho ny lahatsoratr'ity version ity",
+'revdelete-hide-text' => 'Tahirintsoratry ny versiona',
'revdelete-hide-image' => "asitriho ny votoatin'ilay rakitra",
'revdelete-hide-name' => 'Asitriho ny asa sy ny tanjona',
-'revdelete-hide-comment' => 'asitriho ny ambangovangony',
-'revdelete-hide-user' => "Asitriho ny solonanaran'ny mpikambana/adiresy IP",
+'revdelete-hide-comment' => "Ambangovangon'ilay fiovàna",
+'revdelete-hide-user' => "Adiresy IPn'ny Mpanova",
'revdelete-hide-restricted' => "Fafao ireo votoatiny ireo amin'ny mpiandrindra sy amin'ny mpikambana hafa",
'revdelete-radio-same' => '(aza ovaina)',
-'revdelete-radio-set' => 'Eny',
-'revdelete-radio-unset' => 'Tsia',
+'revdelete-radio-set' => 'Afenina',
+'revdelete-radio-unset' => 'Hita maso',
'revdelete-suppress' => "Manitrika ny votoatiny ho an'ny mpandrindra",
'revdelete-unsuppress' => "Hanala ny fepetra eo amin'ny versiona naverina",
'revdelete-log' => 'Antony :',
'shown-title' => 'Aseho valiny $1 isaky ny pejy iray{{PLURAL:}}',
'viewprevnext' => 'Hijery ($1 {{int:pipe-separator}} $2) ($3).',
'searchmenu-exists' => "'''Misy pejy mitondra anarana « [[:$1]] » eto amin'ity wiki ity'''",
-'searchmenu-new' => "'''Hanamboatra ny pejy « [[:$1|$1]] » eto amin'ity wiki ity !'''",
+'searchmenu-new' => "'''Hamorona ny pejy \"[[:\$1]]\" eto amin'ity wiki ity!'''",
'searchprofile-articles' => 'Pejy misy votoatiny',
'searchprofile-project' => 'Pejy fanampiana sy pejy tetikasa',
'searchprofile-images' => 'Multimedia',
'invalid-content-data' => 'Неважечки податоци од содржината',
'content-not-allowed-here' => 'Содржините од моделот „$1“ не се допуштени на страницата [[$2]]',
'editwarning-warning' => 'Ако ја напуштите страницата ќе ги изгубите сите промени кои сте ги направиле.
-Ако сте најавени, можете да го исклучите ова предупредување во одделот „Уредување“ во вашите нагодувања.',
+Ако сте најавени, можете да го исклучите ова предупредување во одделот „{{int:prefs-editing}}“ во вашите нагодувања.',
'editpage-notsupportedcontentformat-title' => 'Форматот на содржината не е поддржан',
'editpage-notsupportedcontentformat-text' => 'Форматот $1 is не е поддржан од содржинскиот модел $2.',
Ве молиме споредете ги промените со претходната верзија за да проверите дали тоа е сигурно она што сакате да го направите, а потоа зачувајте ги промените за да го завршите откажувањето на претходното уредување.',
'undo-failure' => 'Уредувањето не можеше да се откаже заради меѓувремени спротиставени уредувања.',
'undo-norev' => 'Измената не можеше да биде вратена бидејќи не постои или била избришана.',
+'undo-nochange' => 'Се чини дека измената (уредувањето) е веќе вратена.',
'undo-summary' => 'Откажано уредувањето $1 на уредникот [[Special:Contributions/$2|$2]] ([[User talk:$2|разговор]])',
'undo-summary-username-hidden' => 'Поништи ја ревизијата $1 на скриен корисник',
'uploadnewversion-linktext' => 'Подигни нова верзија на податотекава',
'shared-repo-from' => 'од $1',
'shared-repo' => 'заедничко складиште',
-'shared-repo-name-wikimediacommons' => 'Ð\97аедниÑ\87каÑ\82а РизниÑ\86а',
+'shared-repo-name-wikimediacommons' => 'РизниÑ\86аÑ\82а',
'filepage.css' => '/* Тука поставените каскадни стилски страници (CSS) се вклучени во страницата за опис на податотеката, како и на клиентските викија */',
'upload-disallowed-here' => 'Нажалост, не можете да презапишете врз сликава.',
'invalid-content-data' => 'അസാധുവായ ഉള്ളടക്ക ഡേറ്റ',
'content-not-allowed-here' => '"$1" ഉള്ളടക്കം [[$2]] താളിൽ അനുവദിക്കുന്നില്ല',
'editwarning-warning' => 'ഈ താളിൽ നിന്നും പോകുന്നത് താങ്കൾ വരുത്തിയ മാറ്റങ്ങൾ നഷ്ടപ്പെടാൻ ഇടയാക്കും.
-താങ്കൾ ലോഗിൻ ചെയ്തിട്ടുണ്ടെങ്കിൽ, താങ്കളുടെ ക്രമീകരണങ്ങളിൽ "തിരുത്തൽ" എന്ന ഭാഗത്ത് ചെന്ന് ഈ അറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നത് ഒഴിവാക്കാവുന്നതാണ്.',
+താങ്കൾ ലോഗിൻ ചെയ്തിട്ടുണ്ടെങ്കിൽ, താങ്കളുടെ ക്രമീകരണങ്ങളിൽ "{{int:prefs-editing}}" എന്ന ഭാഗത്ത് ചെന്ന് ഈ അറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നത് ഒഴിവാക്കാവുന്നതാണ്.',
'editpage-notsupportedcontentformat-title' => 'ഉള്ളടക്ക ഫോർമാറ്റ് പിന്തുണയ്ക്കുന്നില്ല',
'editpage-notsupportedcontentformat-text' => 'ഉള്ളടക്കത്തിന്റെ ഫോർമാറ്റ് ആയ $1 ഉള്ളടക്ക രീതിയായ $2 പിന്തുണയ്ക്കുന്നില്ല.',
'showhideselectedversions' => 'തിരഞ്ഞെടുത്ത മാറ്റങ്ങൾ പ്രദർശിപ്പിക്കുക/മറയ്ക്കുക',
'editundo' => 'മാറ്റം തിരസ്ക്കരിക്കുക',
'diff-empty' => '(വ്യത്യാസം ഇല്ല)',
+'diff-multi-sameuser' => '(ഒരേ ഉപയോക്താവ് ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)',
+'diff-multi-otherusers' => '({{PLURAL:$2|മറ്റൊരു ഉപയോക്താവ്|$2 ഉപയോക്താക്കൾ}} ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)',
'diff-multi-manyusers' => '(ഇടയ്ക്ക് {{PLURAL:$2|ഒന്നിലധികം|$2 എണ്ണത്തിലധികം}} ഉപയോക്താക്കൾ ചെയ്തിട്ടുള്ള {{PLURAL:$1|ഒരു പതിപ്പ്|$1 പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല.)',
'difference-missing-revision' => 'ഈ വ്യത്യാസത്തിൽ ($1) {{PLURAL:$2|ഒരു നാൾപ്പതിപ്പ്|$2 നാൾപ്പതിപ്പുകൾ}} കാണാനായില്ല.
'shown-title' => '{{PLURAL:$1|ഒരു ഫലം|$1 ഫലങ്ങൾ}} വീതം താളിൽ കാണിക്കുക',
'viewprevnext' => '$1 {{int:pipe-separator}} $2 എണ്ണം കാണുക ($3)',
'searchmenu-exists' => "'''\"[[:\$1]]\" എന്ന തലക്കെട്ടിൽ ഒരു താൾ ഈ വിക്കിയിൽ നിലവിലുണ്ട്'''",
-'searchmenu-new' => "'''ഈ വിക്കിയിൽ \"[[:\$1]]\" താൾ നിർമ്മിക്കുക!'''",
+'searchmenu-new' => '<strong>ഈ വിക്കിയിൽ "[[:$1]]" എന്ന താൾ സൃഷ്ടിക്കുക!</strong> {{PLURAL:$2|0=|ഒപ്പം താങ്കളുടെ തിരയലിനു ലഭിച്ച ഫലമായ ഈ താൾ കാണുക.|ഒപ്പം താങ്കളുടെ തിരയലിനു ലഭിച്ച ഫലങ്ങൾ കാണുക.}}',
'searchprofile-articles' => 'ലേഖനങ്ങളിൽ',
'searchprofile-project' => 'സഹായം, പദ്ധതി താളുകളിൽ',
'searchprofile-images' => 'പ്രമാണങ്ങളിൽ',
'delete-edit-reasonlist' => 'മായ്ക്കലിന്റെ കാരണം തിരുത്തുക',
'delete-toobig' => 'ഈ താളിനു വളരെ വിപുലമായ തിരുത്തൽ ചരിത്രമുണ്ട്. $1 മേൽ {{PLURAL:$1|പതിപ്പുണ്ട്|പതിപ്പുകളുണ്ട്}}. ഇത്തരം താളുകൾ മായ്ക്കുന്നതു {{SITENAME}} സംരംഭത്തിന്റെ നിലനില്പ്പിനെ തന്നെ ബാധിക്കുമെന്നതിനാൽ ഈ താൾ മായ്ക്കുന്നതിനുള്ള അവകാശം പരിമിതപ്പെടുത്തിയിരിക്കുന്നു.',
'delete-warning-toobig' => 'ഈ താളിനു വളരെ വിപുലമായ തിരുത്തൽ ചരിത്രമുണ്ട്. അതായത്, ഇതിനു് $1 മേൽ {{PLURAL:$1|പതിപ്പുണ്ട്|പതിപ്പുകളുണ്ട്}}. ഇത്തരം താളുകൾ മായ്ക്കുന്നതു {{SITENAME}} സംരംഭത്തിന്റെ ഡാറ്റാബേസ് ഓപ്പറേഷനെ ബാധിച്ചേക്കാം. അതിനാൽ വളരെ ശ്രദ്ധാപൂർവ്വം തുടർനടപടികളിലേക്കു നീങ്ങുക.',
-'deleting-backlinks-warning' => "'''മുന്നറിയിപ്പ്:''' മറ്റു താളുകളിൽ നിന്നും താളിലേയ്ക്കുള്ള കണ്ണികൾ താങ്കൾ മായ്ക്കാൻ പോവുകയാണ്.",
+'deleting-backlinks-warning' => "'''à´®àµ\81à´¨àµ\8dനറിയിപàµ\8dà´ªàµ\8d:''' മറàµ\8dà´±àµ\81 താളàµ\81à´\95ളിൽ നിനàµ\8dà´¨àµ\81à´\82 താളിലàµ\87à´¯àµ\8dà´\95àµ\8dà´\95àµ\81à´³àµ\8dà´³ à´\95à´£àµ\8dണിà´\95ൾ à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´\89ൾപàµ\8dà´ªàµ\86à´\9fàµ\81à´¤àµ\8dതിയിà´\9fàµ\8dà´\9fàµ\81à´³àµ\8dà´³ താളàµ\81à´\95ൾ താà´\99àµ\8dà´\95ൾ മായàµ\8dà´\95àµ\8dà´\95ാൻ à´ªàµ\8bà´µàµ\81à´\95യാണàµ\8d.",
# Rollback
'rollback' => 'തിരുത്തലുകൾ റോൾബാക്ക് ചെയ്യുക',
തത്കാലത്തേയ്ക്കു വേണ്ടിയിരുന്ന ഒരു ഫോൾഡർ ലഭ്യമല്ല.',
'import-parse-failure' => 'എക്സ്.എം.എൽ. ഇറക്കുമതി പാഴ്സ് പരാജയം',
'import-noarticle' => 'ഇറക്കുമതി ചെയ്യാൻ താൾ ഇല്ല!',
-'import-nonewrevisions' => 'à´\8eà´²àµ\8dലാ പതിപàµ\8dà´ªàµ\81à´\95à´³àµ\81à´\82 à´®àµ\81à´®àµ\8dà´ªàµ\87 à´\87à´±à´\95àµ\8dà´\95àµ\81മതി à´\9aàµ\86à´¯àµ\8dതിà´\9fàµ\8dà´\9fàµ\81à´³àµ\8dളതാണàµ\8dâ\80\8c.',
+'import-nonewrevisions' => 'à´\92à´°àµ\81 നാൾപàµ\8dപതിപàµ\8dà´ªàµ\81à´\82 à´\87à´±à´\95àµ\8dà´\95àµ\81മതി à´\9aàµ\86à´¯àµ\8dതിà´\9fàµ\8dà´\9fà´¿à´²àµ\8dà´² (à´\8eà´²àµ\8dലാà´\82 നിലവിൽ à´\89à´£àµ\8dà´\9fàµ\8d, à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ പിഴവàµ\81à´\95à´³àµ\81à´³àµ\8dളതിനാൽ à´\92ഴിവാà´\95àµ\8dà´\95à´¿).',
'xml-error-string' => '$2 വരിയിൽ $1, നിര $3 (ബൈറ്റ് $4): $5',
'import-upload' => 'എക്സ്.എം.എൽ. ഡേറ്റ അപ്ലോഡ് ചെയ്യുക',
'import-token-mismatch' => 'സെഷൻ ഡാറ്റ നഷ്ടപ്പെട്ടതിനാൽ ദയവായി വീണ്ടും ശ്രമിക്കൂക',
'expand_templates_generate_rawhtml' => 'അസംസ്കൃത എച്ച്.റ്റി.എം.എൽ. പ്രദർശിപ്പിക്കുക',
'expand_templates_preview' => 'എങ്ങനെയുണ്ടെന്നു കാണുക',
+# Unknown messages
+'uploadinvalidxml' => 'അപ്ലോഡ് ചെയ്ത പ്രമാണത്തിലെ എക്സ്.എം.എൽ. പാഴ്സ് ചെയ്യാൻ കഴിയില്ല.',
);
'recentchanges' => 'Tibdil riċenti',
'recentchanges-legend' => 'Opzjonijiet tat-tibdil riċenti',
'recentchanges-summary' => 'Din il-paġna turi l-modifiki l-aktar riċenti għal kontenut tas-sit.',
+'recentchanges-noresult' => 'L-ebda bidla ma saret matul il-perjodu mogħti li tissodisfa dawn il-kriterji.',
'recentchanges-feed-description' => "Dan il-feed jirraporta l-modifiki l-aktar riċenti fil-kontenut ta' dan is-sit.",
'recentchanges-label-newpage' => 'Din il-modifika ħolqot paġna ġdida',
'recentchanges-label-minor' => 'Din hi modifika minuri',
'content-failed-to-parse' => 'Klarte ikke å tolke innholdet $2 for innholdsmodellen $1: $3',
'invalid-content-data' => 'Ugyldig innhold',
'content-not-allowed-here' => 'Innholdsmodellen «$1» er ikke tillatt på siden [[$2]]',
-'editwarning-warning' => 'Ved å forlate siden kan du miste alle endringer du har utført. Om du er logget inn kan du slå av denne advarselen under «Redigering»-seksjonen i innstillingene.',
+'editwarning-warning' => 'Ved å forlate siden kan du miste alle endringer du har gjort.
+Hvis du er innlogget, kan du slå av denne advarselen under "{{int:prefs-editing}}"-avsnittet i dine innstillinger.',
'editpage-notsupportedcontentformat-title' => 'Innholdsformatet er ikke støttet',
'editpage-notsupportedcontentformat-text' => 'Innholdsformatet $1 er ikke støttet av innholdsmodellen $2.',
'showhideselectedversions' => 'Geselecteerde versies weergeven/verbergen',
'editundo' => 'ongedaan maken',
'diff-empty' => '(geen verschil)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door dezelfde gebruiken niet weergegeven)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} 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)',
'difference-missing-revision' => '{{PLURAL:$2|Eén versie|$2 versies}} van deze verschillen ($1) {{PLURAL:$2|is|zijn}} niet aangetroffen.
'shown-title' => '$1 {{PLURAL:$1|resultaat|resultaten}} per pagina weergeven',
'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) bekijken.',
'searchmenu-exists' => "* Pagina '''[[$1]]'''",
-'searchmenu-new' => "'''De pagina \"[[:\$1]]\" aanmaken op deze wiki.'''",
+'searchmenu-new' => '<strong>Maak de pagina "[[:$1]]" op deze wiki!</strong> {{PLURAL:$2|0=|Zie ook de pagina met uw zoekresultaat. |Zie ook de lijst met gevonden zoekresultaten}}',
'searchprofile-articles' => "Inhoudelijke pagina's",
'searchprofile-project' => "Hulp- en projectpagina's",
'searchprofile-images' => 'Multimedia',
'watchmethod-list' => "controleer pagina's op volglijst op wijzigingen",
'watchlistcontains' => "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst.",
'iteminvalidname' => "Probleem met object '$1', ongeldige naam…",
+'wlnote2' => 'Hieronder staan de veranderingen in {{PLURAL:$1|het|de}} laatste {{PLURAL:$1|uur|<strong> $1 </strong>uren}}, sinds $2, $3.',
'wlshowlast' => 'Laatste $1 uur, $2 dagen bekijken ($3)',
'watchlist-options' => 'Opties voor volglijst',
Een tijdelijke map is niet aanwezig.',
'import-parse-failure' => 'Fout bij het verwerken van de XML-import',
'import-noarticle' => "Er zijn geen te importeren pagina's!",
-'import-nonewrevisions' => 'Alle versies zijn al eerder geïmporteerd.',
+'import-nonewrevisions' => 'Geen revisies geïmporteerd (alle waren al aanwezig, of overgeslagen vanwege fouten).',
'xml-error-string' => '$1 op regel $2, kolom $3 (byte $4): $5',
'import-upload' => 'XML-gegevens uploaden',
'import-token-mismatch' => 'De sessiegegevens zijn verloren gegaan. Probeer het opnieuw.',
'import-error-special' => 'Pagina "$1" is niet geïmporteerd omdat deze is geplaatst in een speciale naamruimte waar geen pagina\'s in geplaatst kunnen worden.',
'import-error-invalid' => 'De pagina" "$1" is niet geïmporteerd omdat de naam ongeldig is.',
'import-error-unserialize' => 'Versie $2 van de pagina "$1" kon niet verwerkt worden. De versie hoort contentmodel $3 te gebruiken met een serialisatie als $4.',
+'import-error-bad-location' => 'Revisie $2 met behulp van model $3 kan niet worden opgeslagen als "$1" op deze wiki, aangezien dat model niet ondersteund wordt op die pagina.',
'import-options-wrong' => 'Verkeerde {{PLURAL:$2|optie|opties}}: <nowiki>$1</nowiki>',
'import-rootpage-invalid' => 'De opgegeven basispagina is ongeldig.',
'import-rootpage-nosubpage' => 'In de naamruimte "$1" van de basispagina is het aanmaken van subpagina\'s niet mogelijk.',
'invalid-content-data' => 'Zawartość strony zawiera nieprawidłowe dane',
'content-not-allowed-here' => 'Zawartość tego typu ($1) nie jest dozwolona na stronie [[$2]]',
'editwarning-warning' => 'Opuszczenie tej strony może spowodować utratę wprowadzonych przez Ciebie zmian.
-Jeśli jesteś zalogowany możesz wyłączyć wyświetlanie tego ostrzeżenia w zakładce Edycja w swoich preferencjach.',
+Jeśli jesteś zalogowany, możesz wyłączyć wyświetlanie tego ostrzeżenia w zakładce „{{int:prefs-editing}}” w swoich preferencjach.',
'editpage-notsupportedcontentformat-title' => 'Nieobsługiwany format zawartości',
# Content models
'shown-title' => 'Pokaż po $1 {{PLURAL:$1|wyniku|wyniki|wyników}} na stronę',
'viewprevnext' => 'Zobacz ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "* Strona '''[[$1]]'''",
-'searchmenu-new' => "'''Utwórz stronę „[[:$1|$1]]” na tej wiki.'''",
+'searchmenu-new' => '<strong>Utwórz stronę „[[:$1]]” na tej wiki!<strong> {{PLURAL:$2|0=|Zobacz też stronę z wynikami wyszukiwania.|Zobacz też wyniki wyszukiwania.}}',
'searchprofile-articles' => 'Strony',
'searchprofile-project' => 'Strony pomocy i projektu',
'searchprofile-images' => 'Multimedia',
'watchmethod-list' => 'poszukiwanie obserwowanych stron wśród ostatnich zmian',
'watchlistcontains' => 'Na liście obserwowanych przez Ciebie stron {{PLURAL:$1|znajduje się 1 pozycja|znajdują się $1 pozycje|znajduje się $1 pozycji}}.',
'iteminvalidname' => 'Problem z pozycją „$1” – niepoprawna nazwa...',
-'wlnote2' => 'Poniżej pokazano zmiany wykonane w ciągu {{PLURAL:$1|ostatniej godziny|ostatnich <strong>$1</strong> godzin}}, licząc od $4, $3.',
+'wlnote2' => 'Poniżej pokazano zmiany wykonane w ciągu {{PLURAL:$1|ostatniej godziny|ostatnich <strong>$1</strong> godzin}}, licząc od $2, $3.',
'wlshowlast' => 'Pokaż ostatnie $1 godzin, $2 dni ($3)',
'watchlist-options' => 'Opcje obserwowanych',
'invalid-content-data' => 'Dat dël contnù pa bon',
'content-not-allowed-here' => "Ël contnù «$1» a l'é nen autorisà an sla pàgina [[$2]]",
'editwarning-warning' => "Chité sta pàgina-sì a peul feje perde tute le modìfiche ch'a l'ha fàit.
-S'a l'é rintrà ant ël sistema, a peul disabilité st'avis ant la session «Modìfica» dij sò gust.",
+S'a l'é rintrà ant ël sistema, a peul disabilité st'avis ant la session «{{int:prefs-editing}}» dij sò gust.",
'editpage-notsupportedcontentformat-title' => 'Formà ëd contnù nen mantnù',
'editpage-notsupportedcontentformat-text' => "Ël formà ëd contnù $1 a l'é nen mantnù dal model Ëd contnù $2.",
* @author Huji
* @author IAlex
* @author INkubusse
+ * @author Incnis Mrsi
* @author Iniquity
* @author Iwan Novirion
* @author Jon Harald Søby
Parameters:
* $1 - number of subcategories shown',
'category-article-count' => 'This message is used on category pages. Parameters:
-* $1 - number of pages shown
-* $2 - total number of pages in category',
+* $1 – number of pages shown
+* $2 – total number of pages in category',
'category-article-count-limited' => 'This message is displayed at the top of a category page showing the number of pages in the category when not all pages in a category are counted.
Parameters:
'category-file-count' => 'This message is displayed at the top of a category page showing the number of pages in the category.
Parameters:
-* $1 - number of files shown
+* $1 – number of files shown
* $2 - total number of files in category',
'category-file-count-limited' => 'This message is displayed at the top of a category page showing the number of pages in the category when not all pages in a category are counted.
'content-not-allowed-here' => 'Error message indicating that the desired content model is not supported in given localtion.
* $1 - the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}
* $2 - the title of the page in question',
-'editwarning-warning' => "{{doc-important|Do ''not'' use <nowiki>{{int:prefs-editing}}</nowiki> for \"Editing\". It is forbidden in this message, see [[mwr:68405]].}}
-
-but you can see the text of that button here: {{msg-mw|Prefs-editing}}",
+'editwarning-warning' => 'Uses {{msg-mw|Prefs-editing}}',
'editpage-notsupportedcontentformat-title' => 'Title of error page shown when using an incompatible format on EditPage',
'editpage-notsupportedcontentformat-text' => 'Error message shown when using an incompatible format on EditPage. Parameters:
* $1 - the format id
'undo-norev' => 'Message appears if an attempt to revert an edit by clicking the "undo" link on the page history fails.
{{Identical|Undo}}',
+'undo-nochange' => 'Message appears if an attempt to revert an edit by clicking the "undo" link results in an edit making no change to the current version of the page.',
'undo-summary' => 'Edit summary for an undo action. Parameters:
* $1 - revision ID
* $2 - username
* $3 - total number of results
* $4 - the search term
* $5 - number of results',
+'showingresultsinrange' => 'Used in pagination of [[Special:MostLinkedCategories]]. Parameters:
+* $1 - the total number of results in the batch shown
+* $2 - the number of the first item listed
+* $3 - the number of last item in the batch shown',
'search-nonefound' => 'Message shown when a search returned no results (when using the default MediaWiki search engine).',
'powersearch-legend' => 'Advanced search
# Variants for Serbian language
'variantname-sr-ec' => '{{optional}}
-Varient Option for wikis with variants conversion enabled.',
+Variant Option for wikis with variants conversion enabled.
+
+Note that <code>sr-ec</code> is not a conforming BCP47 language tag. Wikis should be migrated by:
+* 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),
+* making the new tag the default to look first, before looking for the old tag,
+* moving the translations to the new code by renaming them,
+* checking links in source pages still using the legacy tag to change it to the new tag,
+* possibly cleanup the redirect pages.',
'variantname-sr-el' => '{{optional}}
-Varient Option for wikis with variants conversion enabled.',
+Variant Option for wikis with variants conversion enabled.
+
+Note that <code>sr-el</code> is not a conforming BCP47 language tag. Wikis should be migrated by:
+* 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),
+* making the new tag the default to look first, before looking for the old tag,
+* moving the translations to the new code by renaming them,
+* checking links in source pages still using the legacy tag to change it to the new tag,
+* possibly cleanup the redirect pages.',
'variantname-sr' => '{{optional}}
Varient Option for wikis with variants conversion enabled.',
# Separators for various lists, etc.
'semicolon-separator' => '{{optional}}',
-'comma-separator' => '{{optional}}',
+'comma-separator' => '{{optional}}
+
+Warning: languages have different usages of punctuation, and sometimes they are swapped (e.g. openining and closing quotation marks, or full stop and colon in Armenian), or change their form (the full stop in Chinese and Japanese, the prefered "colon" in Armenian used in fact as the regular full stop, the comma in Arabic, Armenian, and Chinese...)
+
+Their spacing (before or after) may also vary across languages (for example French requires a non-breaking space, preferably narrow if the browser supports NNBSP, on the inner side of some punctuations like quotation/question/exclamation marks, colon, and semicolons).',
'colon-separator' => "{{optional}}
Change it only if your language uses another character for ':' or it needs an extra space before the colon.",
'pipe-separator' => '{{optional}}',
'bitrate-megabits' => '{{optional}}
Bitrate (of a file, typically) in megabits (1 megabits = 1000×1000 bits).',
'bitrate-gigabits' => '{{optional}}
-Bitrate (of a file, typically) in gibibits (1 gigabits = 1000×1000×1000 bits).',
+Bitrate (of a file, typically) in gigabits (1 gigabits = 1000×1000×1000 bits).',
'bitrate-terabits' => '{{optional}}
Bitrate (of a file, typically) in terabits (1 terabits = 1000×1000×1000×1000 bits).',
'bitrate-petabits' => '{{optional}}
'youhavenewmessagesfromusers' => '$1 {{PLURAL:$3|huk ruraqmanta|$3 ruraqkunamanta}} qhawanayki kachkan ($2).',
'youhavenewmessagesmanyusers' => '$1 achka ruraqkunamanta qhawanayki kachkan ($2).',
'newmessageslinkplural' => '{{PLURAL:$1|Musuq willaymi|Musuq willaykunam}}',
-'newmessagesdifflinkplural' => 'qayna {{PLURAL:$1|hukchasqapi|hukchasqakunapi}} wakin kaynin',
+'newmessagesdifflinkplural' => 'ñaqha {{PLURAL:$1|hukchasqa|hukchasqakuna}}',
'youhavenewmessagesmulti' => 'Musuq willaykunam qhawanayki kachkan $1-pi',
'editsection' => "llamk'apuy",
'editold' => "llamk'apuy",
'invalidtitle-knownnamespace' => '"$2" sutisuyu, "$3" qillqasqayuq mana allin kaq qillqa suti',
'invalidtitle-unknownnamespace' => 'Mana riqsisqa $1 kaq sutisuyu yupay, "$2" qillqasqayuq mana allin kaq qillqa suti',
'exception-nologin' => 'Manam yaykurqankichu',
-'exception-nologin-text' => 'Kay wikipiqa icha kay ruranataqa rakiqunaykiwan yaykuspalla ruraytam atinki.',
+'exception-nologin-text' => "Ama hina kaspa [[Special:Userlogin|yaykuy]] kay p'anqaman rinata icha kayta ruranata atinaykipaq.",
# Virus scanner
'virus-badscanner' => "Manam allintachu churapusqa: mana riqsisqa añaw maskaq: ''$1''",
'gotaccount' => "Rakiqunaykiñachu kachkan? '''$1'''.",
'gotaccountlink' => 'Rakiqunaykita willaway',
'userlogin-resetlink' => 'Yaykuna willayniykikunatari qunqarqankichu?',
-'userlogin-resetpassword-link' => 'Yaykuna rimaykita kutichiy',
+'userlogin-resetpassword-link' => 'Yaykuna rimaykita qunqarqankichu?',
'helplogin-url' => 'Help:Yaykuy',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Yaykunapaq yanapa]]',
'userlogin-createanother' => 'Huk rakiqunata kamariy',
'passwordtooshort' => 'Yaykuna rimayqa {{PLURAL:$1|1 icha aswan sanampayuq|$1 icha aswan sanampayuq}} kananmi.',
'password-name-match' => 'Yaykuna rimaykiqa ruraqpa sutiykiman mana kaqlla kananmi.',
'password-login-forbidden' => 'Kay ruraqpa sutinmanqa yaykuna rimanmanpas ama nisqam.',
-'mailmypassword' => 'Musuq yaykuna rimata e-chaskiwan kachamuway',
+'mailmypassword' => 'Yaykuna rimata kutichiy',
'passwordremindertitle' => "{{SITENAME}}paq musuq mit'alla yaykuna rima",
'passwordremindertext' => 'Pipas (qamchiki, $1 IP huchhayuq tiyaymanta) mañakuwarqan {{SITENAME}}paq musuq yaykuna rimatam e-chaski imamaytaykiman kachayta ($4).
"$2" sutiyuq ruraqpa mit\'alla yaykuna rimanqa kamarisqañam, "$3" sutichasqam kachkan. Munarqaspaykiqa, kunan yaykuspa musuq yaykuna rimaykitam akllay.
'throttled-mailpassword' => "Huk yaykuna rima kutichinapaq yuyachina qayna {{PLURAL:$1|huk ura|$1 ura}} mit'api kachamusqañam. {{PLURAL:$1|Huk ura|$1 ura}} mit'apiqa hukllam yaykuna rima yuyachina kachasqa kachun millay rurayta hark'anapaq.",
'mailerror' => 'E-chaskita kachaspa pantasqa: $1',
'acct_creation_throttle_hit' => "Qampa IP huchhaykiyuq kachkaq ruraqkunaqa kay wikita watukuspa ñaqha 24 urapi {{PLURAL:$1|rakiqunaykim|$1 rakiqunaykim}} kamarirqanña. Manam atinkichikchu astawan kichayta huklla p'unchawpi chay IP huchhallayuq kaspa.",
-'emailauthenticated' => "E-chaski imamaytaykiqa $2 p'unchawpi, $3 pachapi chiqapchasqañam.",
-'emailnotauthenticated' => 'E-chaski imamaytaykitaqa manaraqmi takyachirqunkichu. Mana takyachirquptiykiqa, kay qatiq rurachinakunataqa manam atinkichu.',
+'emailauthenticated' => "E-chaski imamaytaykiqa $2 p'unchawpi, $3 pachapi takyachisqañam.",
+'emailnotauthenticated' => 'E-chaski imamaytaykitaqa manaraqmi takyachirqunkichu. Manaraq takyachirquptiykiqa, kay ruranakunapaq manam ima e-chaskipas kachasqa kanchu.',
'noemailprefs' => "E-chaski imamaytaykita willaway kay rurachinakunata llamk'achinapaq.",
'emailconfirmlink' => 'E-chaski imamaytaykita takyachiy',
'invalidemailaddress' => "E-chaski imamaytaykiqa manam allinchu, manachá allinta qillqasqa. Ama hina kaspa, musuq allin sananchayuq imamaytaykita qillqamuy icha k'itichata ch'usaqchay.",
'edit-already-exists' => "Manam atinichu musuq p'anqata kamariyta.
Kachkañam.",
'defaultmessagetext' => 'Ñawpaq qillqa',
-'content-failed-to-parse' => "Manam atinichu $2 samiqta $1 kikinchapaq t'ikrayta: $3",
+'content-failed-to-parse' => 'Manam atinichu $2 samiqta $1 kikinchapaq kuskiyta: $3',
'invalid-content-data' => 'Samiqmanta willaykunaqa manam allinchu',
'content-not-allowed-here' => '"$1" nisqa samiqqa [[$2]] sutiyuq p\'anqapi manam saqillasqachu',
'editwarning-warning' => "Kay p'anqata saqispaykiqa lliw rurarqusqayki hukchasqakunatachá chinkachiykiman.
{{SITENAME}}pi huk kamachiqkunaqa p'anqap pakasqa samiqninta qhawaspa qullusqa kaymanta kutichiyta atinkuraqmi kay kaqlla uyapuratam llamk'achispa, kay wikip kamariqninkuna mana huk saywachanakunata tiyachiptinqa.",
'revdelete-confirm' => 'Ama hina kaspa, takyachiy munayniykita, qatiqninkunata riqsiyniykita, [[{{MediaWiki:Policy-url}}|kawpaykama]] rurayniykitapas.',
'revdelete-suppress-text' => "Pakay ruranata '''kaylla kaptin''' llamk'achiy:
+* K'amiqchá willakuna
* Runamanta mana allin willakuna
-*: ''wasi tiyay imamaytakuna, karu rimay huchhakuna, allin kawsay tarikuq wasimanta huchhakuna, chay hinakunapas.''",
+*: ''wasi tiyay imamaytakuna, karu rimay huchhakuna, mamallaqta sut'inchay huchhakuna, chay hinakunapas.''",
'revdelete-legend' => 'Rikunapaq saywachanakunata tiyachiy',
-'revdelete-hide-text' => 'Qhawana qillqata pakay',
+'revdelete-hide-text' => 'Musuqmanta qhawana qillqa',
'revdelete-hide-image' => 'Willañiqip samiqninta pakay',
'revdelete-hide-name' => 'Rurayta paqtaytapas pakay',
-'revdelete-hide-comment' => "Llamk'apuymanta willapuyta pakay",
-'revdelete-hide-user' => 'Ruraqpa sutinta/IP huchhanta pakay',
+'revdelete-hide-comment' => "Llamk'apuymanta willapuy",
+'revdelete-hide-user' => 'Ruraqpa sutin/IP huchhan',
'revdelete-hide-restricted' => "Kamachiqkunamanta willakunata huk ruraqkunamanta hina hark'ay",
'revdelete-radio-same' => '(ama hukchaychu)',
-'revdelete-radio-set' => 'Arí',
-'revdelete-radio-unset' => 'Ama kachunchu',
+'revdelete-radio-set' => 'Pakasqa',
+'revdelete-radio-unset' => 'Rikunalla',
'revdelete-suppress' => 'Kamachiqkunamantapas willakunata huk ruraqkunamanta hina raqpay',
'revdelete-unsuppress' => "Qullusqamanta paqarisqa llamk'apusqakunapaq saywachanakunata raqpay",
'revdelete-log' => 'Kayrayku:',
'shown-title' => "Huk p'anqapi $1 {{PLURAL:$1|taripasqata|taripasqakunata}} rikuchiy",
'viewprevnext' => 'Qhaway ($1 {{int:pipe-separator}} $2) ($3).',
'searchmenu-exists' => "'''Kay wikipiqa «[[$1]]» sutiyuq p'anqam kachkan'''",
-'searchmenu-new' => "'''Kay wikipi \"[[:\$1]]\" sutiyuq p'anqata kamariy!'''",
+'searchmenu-new' => '<strong>Kay wikipi "[[:$1]]" sutiyuq p\'anqata kamariy!</strong> {{PLURAL:$2|0=|Maskayniykiwan tarisqa p\'anqatapas qhaway.|Maskaywan taripasqakunatapas qhaway.}}\'',
'searchprofile-articles' => "Samiq p'anqakuna",
'searchprofile-project' => "Yanapanapaq ruraykamaypaqpas p'anqakuna",
'searchprofile-images' => 'Multimidya',
'recentchanges-label-minor' => "Kayqa aslla llamk'apuymi",
'recentchanges-label-bot' => "Kayqa rurana antachap llamk'apusqanmi",
'recentchanges-label-unpatrolled' => "Kay llamk'apusqaqa manaraqmi patrullasqachu",
-'recentchanges-legend-newpage' => "$1 - musuq p'anqa",
+'recentchanges-legend-newpage' => "([[Special:NewPages|musuq p'anqakunatapas]] qhaway)",
'rcnotefrom' => "Kay qatiqpiqa '''$2'''-mantapacha ('''$1'''-kama) hukchasqakunatam rikunki.",
'rclistfrom' => '$1-manta musuq hukchasqakunata rikuchiy',
'rcshowhideminor' => "$1 uchuylla llamk'apusqakunata",
Kay p\'anqata mana musuqmanta watukamuptiykiqa, manam huk ruraykunamanta willasqaykichu. Tukuy watiqasqayki p\'anqakunapaq musyachina sananchakunatapas kutichiytam atinkiman.
- Tukuy sunquwan, {{SITENAME}}pa e-chaski musyachina llikan
+Tukuy sunquwan, {{SITENAME}}pa e-chaski musyachina llikan
--
E-chaski willaykuy allinkachinakunata hukchanaykipaqqa kay p\'anqatam qhaway:
'dellogpage' => 'Qullusqakuna',
'dellogpagetext' => 'Kay qatiqpiqa lliwmanta aswan ñaqha qullusqakunatam rikunki. Rikuchisqa pachankunaqa sirwiqpa pachanpim.',
'deletionlog' => 'qullusqakuna',
-'reverted' => 'Ñawpaq hukchasqata kutichiy',
+'reverted' => 'Ñawpaq hukchasqaman kutichisqa',
'deletecomment' => 'Kayrayku:',
'deleteotherreason' => 'Huk rayku:',
'deletereasonotherlist' => 'Huk rayku',
'range_block_disabled' => "Kamachiqpa patayayku hark'ay hayñinman ama nisqam.",
'ipb_expiry_invalid' => 'Puchukana pachaqa manam allinchu.',
'ipb_expiry_temp' => "Pakasqa ruraqpa sutin hark'aykunaqa tiyaqllam kachun.",
-'ipb_hide_invalid' => "Manam atinichu kay rakiqunata ñit'ipayta; nisyu llamk'apusqayuqñachá.",
+'ipb_hide_invalid' => "Manam atinichu kay rakiqunata ñit'ipayta; nisyu {{PLURAL:$1|llamk'apusqayuqñachá}}.",
'ipb_already_blocked' => '"$1" sutiyuqqa hark\'asqañam kachkan.',
'ipb-needreblock' => "$1 sutiyuqqa hark'asqañam. Allinchanakunata hukchayta munankichu?",
'ipb-otherblocks-header' => "Huk {{PLURAL:$1|hark'ay|hark'aykuna}}",
'importuploaderrorsize' => 'Manam atinichu hawamanta chaskina willañiqita churkuyta, saqillasqamanta aswan hatun kaptinmi.',
'importuploaderrorpartial' => 'Manam atinichu hawamanta chaskina willañiqita churkuyta, rakillam churkusqa.',
'importuploaderrortemp' => "Manam atinichu hawamanta chaskina willañiqita churkuyta, mit'alla willañiqi churana mana kaptinmi.",
-'import-parse-failure' => "Manam atinichu XML qillqata t'ikraspa hawamanta chaskiyta",
+'import-parse-failure' => 'Manam atinichu XML qillqata kuskispa hawamanta chaskiyta',
'import-noarticle' => "Manam hawamanta chaskina p'anqachu!",
'import-nonewrevisions' => 'Tukuy musuqchasqakunaqa ñawpaqtañam hawamanta chaskisqa.',
'xml-error-string' => "$1, $2 siq'ipi, $3 tunupi (byte $4): $5",
'svg-long-desc' => 'SVG willañiqi, rimasqakama $1 × $2 iñuyuq, willañiqip chhikan kaynin: $3',
'svg-long-desc-animated' => 'Kuyuchisqa SVG willañiqi, rimasqakama $1 × $2 iñuyuq, willañiqip chhikan kaynin: $3',
'svg-long-error' => 'Mana allin SVG willañiqi: $1',
-'show-big-image' => 'Qallariy huyaku',
+'show-big-image' => 'Qallariy willañiqi',
'show-big-image-preview' => 'Kay ñawpaq qhawariypa chhikan kaynin: $1.',
'show-big-image-other' => 'Huk {{PLURAL:$2|huyaku|huyakukuna}}: $1.',
'show-big-image-size' => '$1 × $2 iñu',
'expand_templates_remove_comments' => 'Willapusqakunata qichuy',
'expand_templates_preview' => 'Ñawpaqta qhawallay',
+# Unknown messages
+'uploadinvalidxml' => 'Manam atinichu churkusqa willañiqipi XML-ta kuskiyta.',
);
'summary' => 'Rezumat:',
'subject' => 'Subiect / titlu:',
'minoredit' => 'Aceasta este o modificare minoră',
-'watchthis' => 'Monitorizează această pagină',
+'watchthis' => 'Urmărește această pagină',
'savearticle' => 'Salvare pagină',
'preview' => 'Previzualizare',
'showpreview' => 'Previzualizare',
'invalid-content-data' => 'Date de conținut invalide',
'content-not-allowed-here' => 'Conținutul de tip „$1” nu este permis pe pagina [[$2]]',
'editwarning-warning' => 'Părăsind această pagină, există riscul pierderii modificărilor efectuate.
-Dacă sunteți autentificat, puteți dezactiva această avertizare în secțiunea „Modificare” a preferințelor dumneavoastră.',
+Dacă sunteți autentificat, puteți dezactiva această avertizare în secțiunea „{{int:prefs-editing}}” a preferințelor dumneavoastră.',
'editpage-notsupportedcontentformat-title' => 'Formatul conținutului nu este acceptat',
'editpage-notsupportedcontentformat-text' => 'Formatul de conținut $1 nu este acceptat de modelul de conținut $2.',
'showhideselectedversions' => 'Șterge/recuperează versiunile marcate',
'editundo' => 'anulare',
'diff-empty' => '(Nicio diferență)',
+'diff-multi-sameuser' => '(Nu {{PLURAL:$1|s-a afișat o versiune intermediară efectuată|s-au afișat $1 versiuni intermediare efectuate|s-au afișat $1 de versiuni intermediare efectuate}} de același utilizator)',
+'diff-multi-otherusers' => '(Nu {{PLURAL:$1|s-a afișat o versiune intermediară efectuată|s-au afișat $1 versiuni intermediare efectuate|s-au afișat $1 de versiuni intermediare efectuate}} de {{PLURAL:$2|un alt utilizator|alți $2 utilizatori|alți $2 de utilizatori}})',
'diff-multi-manyusers' => '({{PLURAL:$1|O versiune intermediară efectuată de|$1 (de) versiuni intermediare efectuate de peste}} $2 {{PLURAL:$2|utilizator|utilizatori}} {{PLURAL:$1|neafișată|neafișate}})',
'difference-missing-revision' => '{{PLURAL:$2|O versiune a|$2 versiuni ale|$2 de versiuni ale}} acestei diferențe ($1) nu {{PLURAL:$2|a fost găsită|au fost găsite}}.
'hidden-category-category' => 'Скрытые категории',
'category-subcat-count' => '{{PLURAL:$2|Эта категория содержит только следующую подкатегорию.|Эта категория содержит $1 {{PLURAL:$1|1=подкатегорию|подкатегории}} из $2 всего.}}',
'category-subcat-count-limited' => 'В этой категории {{PLURAL:$1|$1 подкатегория|$1 подкатегорий|$1 подкатегории}}.',
-'category-article-count' => '{{PLURAL:$2|Эта категория содержит единственную страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страниц|Показаны $1 страницы}} из $2, {{PLURAL:$2|находящейся|находящихся|находящихся}} в данной категории.}}',
+'category-article-count' => '{{PLURAL:$2|Эта категория содержит единственную страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страниц|Показаны $1 страницы}} из $2, находящихся в данной категории.}}',
'category-article-count-limited' => 'В этой категории {{PLURAL:$1|$1 страница|$1 страниц|$1 страницы|1=только одна страница}}.',
-'category-file-count' => '{{PLURAL:$2|Эта категория содержит единственный файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файлов|Показаны $1 файла}} из $2, {{PLURAL:$2|находящегося|находящихся|находящихся}} в данной категории.}}',
+'category-file-count' => '{{PLURAL:$2|Эта категория содержит единственный файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файлов|Показаны $1 файла}} из $2, находящихся в данной категории.}}',
'category-file-count-limited' => 'В этой категории {{PLURAL:$1|$1 файл|$1 файлов|$1 файла|1=только один файл}}.',
'listingcontinuesabbrev' => '(продолжение)',
'index-category' => 'Индексируемые страницы',
'content-failed-to-parse' => 'Содержимое $2 не соответствует типу $1: $3.',
'invalid-content-data' => 'Недопустимые данные',
'content-not-allowed-here' => 'Содержимое "$1" недопустимо на странице [[$2]]',
-'editwarning-warning' => 'Переход на другую страницу может привести к потере сделанных вами изменений.
-Если вы зарегистрированы в системе, то вы можете отключить это предупреждение в разделе «Редактирование» ваших настроек.',
+'editwarning-warning' => 'Переход на другую страницу может привести к потере внесённых вами изменений.
+Если вы зарегистрированы в системе, то вы можете отключить это предупреждение в разделе «{{int:prefs-editing}}» ваших настроек.',
'editpage-notsupportedcontentformat-title' => 'Формат содержимого не поддерживается',
'editpage-notsupportedcontentformat-text' => 'Формат содержимого $1 не поддерживается моделью содержимого $2.',
'undo-success' => 'Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.',
'undo-failure' => 'Правка не может быть отменена из-за несовместимости промежуточных изменений.',
'undo-norev' => 'Правка не может быть отменена, так как её не существует или она была удалена.',
+'undo-nochange' => 'Правка, похоже, уже была отменена.',
'undo-summary' => 'Отмена правки $1, сделанной {{GENDER:$2|участником|участницей}} [[Special:Contributions/$2|$2]] ([[User talk:$2|обс.]])',
'undo-summary-username-hidden' => 'Отмена правки $1, сделанной участником, чьё имя скрыто',
'invalid-content-data' => 'Neveljavni podatki vsebine',
'content-not-allowed-here' => 'Vsebina »$1« ni dovoljena na strani [[$2]]',
'editwarning-warning' => 'Če zapustite stran, boste morda izgubili vse spremembe, ki ste jih naredili.
-Če ste prijavljeni, lahko to opozorilo onemogočite v razdelku »Urejanje« v svojih nastavitvah.',
+Če ste prijavljeni, lahko to opozorilo onemogočite v razdelku »{{int:prefs-editing}}« v svojih nastavitvah.',
'editpage-notsupportedcontentformat-title' => 'Oblika vsebine ni podprta',
'editpage-notsupportedcontentformat-text' => 'Model vsebine $2 ne podpira oblike vsebine $1.',
'undo-success' => 'Urejanje ste razveljavili. Prosimo, preverite prikazano primerjavo redakcij in, če ustrezajo, shranite spremembe.',
'undo-failure' => 'Zaradi navzkrižij urejanj, ki so se vmes pojavila, tega urejanja ni moč razveljaviti.',
'undo-norev' => 'Urejanja ni mogoče razveljaviti, ker ne obstaja ali je bilo izbrisano.',
+'undo-nochange' => 'Zdi se, da je urejanje nekdo že razveljavil.',
'undo-summary' => 'Redakcija $1 uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) razveljavljena',
'undo-summary-username-hidden' => 'Razveljavi redakcijo $1 skritega uporabnika',
{{PLURAL:$3|Пожељна врста датотеке је|Пожељне врсте датотека су}} $2.',
'filetype-banned-type' => "'''„.$1“''' {{PLURAL:$4|је забрањена врста датотеке|су забрањене врсте датотека}}.
{{PLURAL:$3|Дозвољена врста датотеке је|Дозвољене врсте датотека су}} $2.",
-'filetype-missing' => 'Ова датотека нема екстензију.',
+'filetype-missing' => 'Ова датотека нема екстензију (нпр. „.jpg“).',
'empty-file' => 'Послата датотека је празна.',
'file-too-large' => 'Послата датотека је превелика.',
'filename-tooshort' => 'Назив датотеке је прекратак.',
{{PLURAL:$3|Poželjna vrsta datoteke je|Poželjne vrste datoteka su}} $2.',
'filetype-banned-type' => "'''„.$1“''' {{PLURAL:$4|je zabranjena vrsta datoteke|su zabranjene vrste datoteka}}.
{{PLURAL:$3|Dozvoljena vrsta datoteke je|Dozvoljene vrste datoteka su}} $2.",
-'filetype-missing' => 'Ova datoteka nema ekstenziju.',
+'filetype-missing' => 'Ova datoteka nema ekstenziju (npr. „.jpg“).',
'empty-file' => 'Poslata datoteka je prazna.',
'file-too-large' => 'Poslata datoteka je prevelika.',
'filename-tooshort' => 'Naziv datoteke je prekratak.',
'invalid-content-data' => 'Ogiltig innehållsdata',
'content-not-allowed-here' => 'innehåll av "$1" är inte tillåtet på sidan [[$2]]',
'editwarning-warning' => 'Om du lämnar den här sidan kommer du att förlora alla ändringar du har gjort.
-Om du är inloggad kan du slå av den här varningen under "Redigering" i dina inställningar.',
+Om du är inloggad kan du slå av den här varningen under "{{int:prefs-editing}}" i dina inställningar.',
'editpage-notsupportedcontentformat-title' => 'Innehållsformat stöds inte',
'editpage-notsupportedcontentformat-text' => 'Innehållsformatet $1 stöds inte av innehållsmodellen $2.',
'showhideselectedversions' => 'Visa/dölj valda versioner',
'editundo' => 'gör ogjord',
'diff-empty' => '(Ingen skillnad)',
+'diff-multi-sameuser' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av samma användare visas inte)',
+'diff-multi-otherusers' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av {{PLURAL:$2|en annan användare|$2 användare}} visas inte)',
'diff-multi-manyusers' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av mer än $2 användare visas inte)',
'difference-missing-revision' => '{{PLURAL:$2|En revision|$2 revisioner}} av denna skillnad ($1) kunde inte hittas.
'watchmethod-list' => 'letar efter nyligen gjorda ändringar bland bevakade sidor',
'watchlistcontains' => 'Din bevakningslista innehåller $1 {{PLURAL:$1|sida|sidor}}.',
'iteminvalidname' => "Problem med ''$1'', ogiltigt namn...",
-'wlnote2' => 'Nedan finns de senaste $1 ändringarna under {{PLURAL:$1|den senaste timmen|de senaste <strong>$2</strong> timmarna}} från den $3 kl. $4.',
+'wlnote2' => 'Nedan finns ändringarna från {{PLURAL:$1|den senaste timmen|de senaste <strong>$1</strong> timmarna}}, med början den $2 kl. $3.',
'wlshowlast' => 'Visa senaste $1 timmarna $2 dygnen $3',
'watchlist-options' => 'Alternativ för bevakningslistan',
'invalid-content-data' => 'తప్పుడు విషయం',
'content-not-allowed-here' => '[[$2]] పేజీలో పాఠ్యం "$1" కి అనుమతి లేదు',
'editwarning-warning' => 'ఈ పేజీని వదిలివెళ్ళడం వల్ల మీరు చేసిన మార్పులను కోల్పోయే అవకాశం ఉంది.
-à°®à±\80à°°à±\81 à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿à°µà±\81à°\82à°\9fà±\87, à°\88 à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95ని à°®à±\80 à°\85à°à°¿à°°à±\81à°\9aà±\81లలà±\8b "మరపà±\81à°²à±\81" à°\85à°¨à±\87 విభాగంలో అచేతనం చేసుకోవచ్చు.',
+à°®à±\80à°°à±\81 లాà°\97à°¿à°¨à±\8d à°\85యివà±\81à°\82à°\9fà±\87, à°\88 à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95ని à°®à±\80 à°\85à°à°¿à°°à±\81à°\9aà±\81లలà±\8bని "{{int:prefs-editing}}" విభాగంలో అచేతనం చేసుకోవచ్చు.',
'editpage-notsupportedcontentformat-title' => 'పాఠ్యపు ఆకృతికి మద్దతు లేదు',
'editpage-notsupportedcontentformat-text' => '$2 పాఠ్యపు మోడల్, పాఠ్యపు ఆకృతి $1 కి మద్దతు ఇవ్వదు',
'undo-failure' => 'మధ్యలో జరిగిన దిద్దుబాట్లతో తలెత్తిన ఘర్షణ కారణంగా ఈ దిద్దుబాటును రద్దు చెయ్యలేక పోయాం.',
'undo-norev' => 'ఈ దిద్దుబాటును అసలు లేకపోవటం వలన, లేదా తొలగించేయడం వలన రద్దుచేయలేకపోతున్నాం.',
'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|చర్చ]]) దిద్దుబాటు చేసిన కూర్పు $1 ను రద్దు చేసారు',
+'undo-summary-username-hidden' => 'దాచబడిన వాడుకరి చేసిన కూర్పు $1 ని వెనక్కి తిప్పండి',
# Account creation failure
'cantcreateaccounttitle' => 'ఈ ఖాతా తెరవలేము',
'right-hideuser' => 'ప్రజలకు కనబడకుండా చేసి, సభ్యనామాన్ని నిరోధించు',
'right-ipblock-exempt' => 'ఐపీ నిరోధాలు, ఆటో నిరోధాలు, శ్రేణి నిరోధాలను తప్పించు',
'right-proxyunbannable' => 'ప్రాక్సీల ఆటోమాటిక్ నిరోధాన్ని తప్పించు',
-'right-unblockself' => 'వారినà±\87 à°\85నిరà±\8bధిà°\82à°\9aà±\81à°\95à±\8bవడం',
+'right-unblockself' => 'à°¸à±\8dà°µà±\80à°¯ à°\85నిరà±\8bà°§ం',
'right-protect' => 'సంరక్షణ స్థాయిలను మార్చు, సంరక్షిత పేజీలలో దిద్దుబాటు చెయ్యి',
'right-editprotected' => '"{{int:protect-level-sysop}}" గా సంక్షించబడిన పేజీలను సరిదిద్దు',
'right-editsemiprotected' => '"{{int:protect-level-autoconfirmed}}" గా సంరక్షించబడ్డ పేజీలను మార్చు',
'upload-http-error' => 'ఒక HTTP పొరపాటు జరిగింది: $1',
# File backend
+'backend-fail-stream' => '"$1" ఫైలును స్ట్రీమింగు చెయ్యలేకపోయాం.',
+'backend-fail-backup' => '"$1" ఫైలును బ్యాకప్పు చెయ్యలేకపోయాం.',
'backend-fail-notexists' => '$1 ఫైలు అసలు లేనేలేదు.',
+'backend-fail-hashes' => 'పోలిక కోసం ఫైలు హాష్లను పొందలేకపోయాం.',
+'backend-fail-notsame' => 'సరిగ్గా సరిపోయే ఫైలు కాదు గానీ, ఒక ఫైలు ఈసరికే "$1" వద్ద ఉంది.',
+'backend-fail-invalidpath' => '"$1" సరైన స్టోరేజి పాత్ కాదు',
'backend-fail-delete' => '$1 ఫైలును తొలగించలేకున్నాం.',
+'backend-fail-describe' => '"$1" ఫైలు మెటాడేటాను మార్చలేకపోయాం.',
'backend-fail-alreadyexists' => '$1 అనే దస్త్రం ఇప్పటికే ఉంది.',
+'backend-fail-store' => '"$1" ఫైలును "$2" వద్ద భద్రపరచలేకపోయాం.',
+'backend-fail-copy' => '"$1" నుండి "$2" కి ఫైలును కాపీ చెయ్యలేకపోయాం.',
+'backend-fail-move' => '"$1" నుండి "$2" కి ఫైలును తరలించలేకపోయాం.',
'backend-fail-opentemp' => 'తాత్కాలిక దస్త్రాన్ని తెరవలేకపోతున్నాం.',
+'backend-fail-writetemp' => 'తాత్కాలిక ఫైలులో రాయలేకపోయాం.',
'backend-fail-closetemp' => 'తాత్కాలిక దస్త్రాన్ని మూసివేయలేకపోయాం.',
'backend-fail-read' => '$1 దస్త్రము చదువలేకపోతిమి.',
'backend-fail-create' => '$1 ఫైలులో రాయలేకున్నాం.',
+'backend-fail-maxsize' => '"$1" ఫైలు {{PLURAL:$2|ఒక బైట్|$2 బైట్ల}} కంటే పెద్దది కావడం చేత దాన్ని రాయలేకపోయాం.',
+'backend-fail-readonly' => 'స్టోరేజి బ్యాక్ఎండ్ "$1" ప్రస్తుతం రీడ్-ఓన్లీ స్థితిలో ఉంది. దానికి కారణం: "<em>$2</em>"',
+'backend-fail-connect' => 'స్టోరేజీ బ్యాక్ఎండ్ "$1" కి కనెక్టు కాలేక పోయాం.',
+'backend-fail-internal' => 'స్టోరేజీ బ్యాక్ఎండ్ "$1" లో ఏదో తెలియని లోపం దొర్లింది.',
+'backend-fail-contenttype' => '"$1" లో దాచాల్సిన ఫైలు యొక్క కంటెంటు రకమేంటో నిర్ధారించలేకపోయాం.',
+'backend-fail-batchsize' => 'స్టోరేజీ బ్యాక్ఎండ్ కు $1 ఫైలు {{PLURAL:$1|ఆపరేషన్|ఆపరేషన్ల}} తో కూడిన బ్యాచ్ ఒకటి ఇవ్వబడింది; పరిమితి: $2 {{PLURAL:$2|ఆపరేషన్|ఆపరేషన్లు}}.',
# ZipDirectoryReader
'zip-file-open-error' => 'ఈ ఫైలును ZIP పరీక్ష కోసం తెరవబోతే, ఏదో తెలియని లోపం ఎదురైంది.',
'ninterwikis' => '$1 {{PLURAL:$1|అంతర్వికీ|అంతర్వికీలు}}',
'nlinks' => '$1 {{PLURAL:$1|లింకు|లింకులు}}',
'nmembers' => '{{PLURAL:$1|ఒక ఉపవర్గం/పేజీ/ఫైలు|$1 ఉపవర్గాలు/పేజీలు/ఫైళ్లు}}',
+'nmemberschanged' => '$1 → $2 {{PLURAL:$2|సభ్యుడు|సభ్యులు}}',
'nrevisions' => '{{PLURAL:$1|ఒక సంచిక|$1 సంచికలు}}',
'nviews' => '$1 {{PLURAL:$1|దర్శనము|దర్శనలు}}',
'nimagelinks' => '$1 {{PLURAL:$1|పుట|పుటల}}లో ఉపయోగించారు',
'mostlinkedtemplates' => 'ఎక్కువగా ఉపయోగించిన మూసలు',
'mostcategories' => 'అధిక వర్గాలలో చేరిన వ్యాసాలు',
'mostimages' => 'అధిక లింకులు గల బొమ్మలు',
+'mostinterwikis' => 'అత్యధిక అంతరవికీ లింకులు కలిగిన పేజీలు',
'mostrevisions' => 'అధిక సంచికలు గల వ్యాసాలు',
'prefixindex' => 'ఉపసర్గతో అన్ని పేజీలు',
'prefixindex-namespace' => 'ఉపసర్గతో ఉన్న పేజీలు ($1 పేరుబరి)',
+'prefixindex-strip' => 'జాబితాలో ఆదిపదాన్ని తీసివేయి',
'shortpages' => 'చిన్న పేజీలు',
'longpages' => 'పొడవు పేజీలు',
'deadendpages' => 'అగాధ (డెడ్ఎండ్) పేజీలు',
'protectedpages' => 'సంరక్షిత పేజీలు',
'protectedpages-indef' => 'అనంత సంరక్షణ మాత్రమే',
'protectedpages-cascade' => 'కాస్కేడింగు రక్షణలు మాత్రమే',
+'protectedpages-noredirect' => 'దారిమార్పులను దాచు',
'protectedpagesempty' => 'ఈ పరామితులతో ప్రస్తుతం ఏ పేజీలు కూడా సంరక్షించబడి లేవు.',
'protectedtitles' => 'సంరక్షిత శీర్షికలు',
'protectedtitlesempty' => 'ఈ పరామితులతో ప్రస్తుతం శీర్షికలేమీ సరక్షించబడి లేవు.',
'listusers' => 'వాడుకరుల జాబితా',
'listusers-editsonly' => 'మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు',
'listusers-creationsort' => 'చేరిన తేదీ క్రమంలో చూపించు',
+'listusers-desc' => 'అవోహణ క్రమంలో పేర్చు',
'usereditcount' => '$1 {{PLURAL:$1|మార్పు|మార్పులు}}',
'usercreated' => '$1 న $2కి {{GENDER:$3|చేరారు}}',
'newpages' => 'కొత్త పేజీలు',
'linksearch-pat' => 'వెతకాల్సిన నమూనా:',
'linksearch-ns' => 'పేరుబరి:',
'linksearch-ok' => 'వెతుకు',
-'linksearch-text' => '"*.wikipedia.org" వంటి వైల్డ్ కార్డులు వాడవచ్చు.<br />ఉపయోగించుకోగల ప్రోటోకాళ్లు: <code>$1</code>',
+'linksearch-text' => '"*.wikipedia.org" వంటి వైల్డ్ కార్డులు వాడవచ్చు. కనీసం ఒక్కటైనా టాప్ లెవెల్ డొమెయిన్ ఉండాలి. ఉదా: "*.org".<br />ఉపయోగించుకోగల {{PLURAL:$2|ప్రోటోకోల్|ప్రోటోకోళ్లు}}: <code>$1</code> (ఏ ప్రోటోకోలునూ ఇవ్వకపోతే, http:// ను వాడబడుతుంది)',
'linksearch-line' => '$2 నుండి $1కి లింకు ఉంది',
'linksearch-error' => 'హోస్ట్నేముకు ముందు మాత్రమే వైల్డ్ కార్డులు వాడవచ్చు.',
'emailuser-title-target' => 'ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపించండి',
'emailuser-title-notarget' => 'ఈ-మెయిలు వాడుకరి',
'emailpage' => 'వాడుకరికి ఈ-మెయిలుని పంపించు',
-'emailpagetext' => 'వాడà±\81à°\95à°°à°¿à°\95à°¿ ఈమెయిలు సందేశము పంపించుటకు క్రింది ఫారంను ఉపయోగించవచ్చు. [[Special:Preferences|మీ వాడుకరి అభిరుచుల]]లో మీరిచ్చిన ఈ-మెయిలు చిరునామా "నుండి" ఆ సందేశం వచ్చినట్లుగా ఉంటుంది, కనుక వేగుని అందుకునేవారు నేరుగా మీకు జవాబివ్వగలుగుతారు.',
+'emailpagetext' => 'à°\88 {{GENDER:$1|వాడà±\81à°\95à°°à°¿à°\95à°¿}} ఈమెయిలు సందేశము పంపించుటకు క్రింది ఫారంను ఉపయోగించవచ్చు. [[Special:Preferences|మీ వాడుకరి అభిరుచుల]]లో మీరిచ్చిన ఈ-మెయిలు చిరునామా "నుండి" ఆ సందేశం వచ్చినట్లుగా ఉంటుంది, కనుక వేగుని అందుకునేవారు నేరుగా మీకు జవాబివ్వగలుగుతారు.',
'usermailererror' => 'మెయిలు ఆబ్జెక్టు ఈ లోపాన్ని చూపింది:',
'defemailsubject' => 'వాడుకరి "$1" నుండి {{SITENAME}} ఈ-మెయిలు',
'usermaildisabled' => 'వాడుకరి ఈ-మెయిళ్ళు అచేతనం చేసారు',
'watchnologin' => 'లాగిన్ అయిలేరు',
'watchnologintext' => 'మీ వీక్షణ జాబితాను మార్చడానికి మీరు [[Special:UserLogin|లాగిన్]] అయి ఉండాలి.',
'addwatch' => 'వీక్షణ జాబితాలో చేర్చు',
-'addedwatchtext' => "\"[[:\$1]]\" అనే పుట మీ [[Special:Watchlist|వీక్షణ జాబితా]]లో చేరింది.
-భవిష్యత్తులో ఈ పుటకి మరియు సంబంధిత చర్చాపుటకి జరిగే మార్పులు అక్కడ కనిపిస్తాయి, మరియు [[Special:RecentChanges|ఇటీవలి మార్పుల జాబితా]]లో సులభంగా గుర్తించడానికి ఈ పుట '''బొద్దుగా''' కనిపిస్తుంది.",
+'addedwatchtext' => '"[[:$1]]" అనే పుట మీ [[Special:Watchlist|వీక్షణ జాబితా]]లో చేరింది.
+భవిష్యత్తులో ఈ పుటకి మరియు సంబంధిత చర్చాపుటకి జరిగే మార్పులు అక్కడ కనిపిస్తాయి.',
'removewatch' => 'వీక్షణ జాబితా నుండి తొలగించు',
'removedwatchtext' => '"[[:$1]]" అనే పేజీ [[Special:Watchlist|మీ వీక్షణ జాబితా]] నుండి తొలగించబడినది.',
'watch' => 'వీక్షించు',
'notanarticle' => 'వ్యాసం పేజీ కాదు',
'notvisiblerev' => 'ఈ కూర్పును తొలగించాం',
'watchlist-details' => 'మీ వీక్షణ జాబితాలో {{PLURAL:$1|ఒక పేజీ ఉంది|$1 పేజీలు ఉన్నాయి}}, చర్చా పేజీలని వదిలేసి.',
-'wlheader-enotif' => 'à°\88-à°®à±\86యిలà±\81 à°ªà±\8dà°°à°\95à°\9fà°¨లు పంపబడతాయి.',
-'wlheader-showupdated' => "మీ గత సందర్శన తరువాత మారిన పేజీలు '''బొద్దు'''గా చూపించబడ్డాయి.",
+'wlheader-enotif' => 'à°\88-à°®à±\86యిలà±\81 à°\97మనిà°\95లు పంపబడతాయి.',
+'wlheader-showupdated' => 'మీ గత సందర్శన తరువాత మారిన పేజీలు <strong>బొద్దు</strong>గా చూపించబడ్డాయి.',
'watchmethod-recent' => 'వీక్షణ జాబితాలోని పేజీల కొరకు ఇటీవలి మార్పులు పరిశీలించబడుతున్నాయి',
'watchmethod-list' => 'ఇటీవలి మార్పుల కొరకు వీక్షణ జాబితాలోని పేజీలు పరిశీలించబడుతున్నాయి',
'watchlistcontains' => 'మీ వీక్షణ జాబితాలో {{PLURAL:$1|ఒక పేజీ ఉంది|$1 పేజీలు ఉన్నాయి}}.',
'iteminvalidname' => "'$1' తో ఇబ్బంది, సరైన పేరు కాదు...",
+'wlnote2' => '$2, $3 సమయానికి, గత {{PLURAL:$1|గంటలో|<strong>$1</strong> గంటల్లో}}, జరిగిన మార్పులు కింద ఇవ్వబడ్డాయి.',
'wlshowlast' => 'గత $1 గంటలు $2 రోజులు $3 చూపించు',
'watchlist-options' => 'వీక్షణ జాబితా ఎంపికలు',
'blocklist-userblocks' => 'ఖాతా నిరోధాలను దాచు',
'blocklist-tempblocks' => 'తాత్కాలిక నిరోధాలను దాచు',
'blocklist-addressblocks' => 'ఏకైక ఐపీ నిరోధాలను దాచు',
+'blocklist-rangeblocks' => 'శ్రేణి నిరోధకాలను దాచు',
'blocklist-timestamp' => 'కాలముద్ర',
'blocklist-target' => 'గమ్యం',
'blocklist-expiry' => 'కాలం చేల్లేది',
వివరాల కోసం అణచివేత చిట్టా కింద చూపబడింది:',
'blocklogentry' => '"[[$1]]" పై నిరోధం అమలయింది. నిరోధ కాలం $2 $3',
'reblock-logentry' => '[[$1]] కై నిరోధపు అమరికలను $2 $3 గడువుతో మార్చారు',
-'blocklogtext' => 'వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది. ఆటోమాటిక్గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు. ప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|ఐ.పి. నిరోధాల జాబితా]]ను చూడండి.',
+'blocklogtext' => 'వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది.
+ఆటోమాటిక్గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు.
+ప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|నిరోధాల జాబితా]]ను చూడండి.',
'unblocklogentry' => '$1పై నిరోధం తొలగించబడింది',
'block-log-flags-anononly' => 'అజ్ఞాత వాడుకర్లు మాత్రమే',
'block-log-flags-nocreate' => 'ఖాతా సృష్టించడాన్ని అశక్తం చేసాం',
'range_block_disabled' => 'శ్రేణి(రేంజి) నిరోధం చెయ్యగల నిర్వాహక అనుమతిని అశక్తం చేసాం.',
'ipb_expiry_invalid' => 'అంతమయ్యే గడువు సరైనది కాదు.',
'ipb_expiry_temp' => 'దాచిన వాడుకరిపేరు నిరోధాలు శాశ్వతంగా ఉండాలి.',
-'ipb_hide_invalid' => 'à°\88 à°\96ాతానà±\81 à°\85à°£à°\9aà°²à±\87à°\95à°ªà±\8bà°¤à±\81à°¨à±\8dనాà°\82. దాని à°\95à°¿à°\82à°¦ à°\9aాలా దిదà±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\89à°\82à°¡à°¿ à°\89à°\82à°\9fాయి.',
+'ipb_hide_invalid' => 'à°\88 à°\96ాతానà±\81 à°\85à°£à°\9aà°²à±\87à°\95à°ªà±\8bà°¤à±\81à°¨à±\8dనాà°\82. దాని à°\96ాతాలà±\8b {{PLURAL:$1|à°\92à°\95à°\9fà°¿ à°\95à°\82à°\9fà±\87|$1 à°\95à°\82à°\9fà±\87}} à°\8eà°\95à±\8dà°\95à±\81à°µ దిదà±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\89à°¨à±\8dà°¨ాయి.',
'ipb_already_blocked' => '"$1" ను ఇప్పటికే నిరోధించాం',
'ipb-needreblock' => '$1ని ఇప్పటికే నిరోధించారు. ఆ అమరికలని మీరు మార్చాలనుకుంటున్నారా?',
'ipb-otherblocks-header' => 'ఇతర {{PLURAL:$1|నిరోధం|నిరోధాలు}}',
పేజీలను ఎగుమతి చేసందుకు, కింద ఇచ్చిన టెక్స్టు బాక్సులో పేజీ పేర్లను లైనుకో పేరు చొప్పున ఇవ్వండి. ప్రస్తుత కూర్పుతో పాటు పాత కూర్పులు కూడా కావాలా, లేక ప్రస్తుత కూర్పు మాత్రమే చాలా అనే విషయం కూడా ఇవ్వవచ్చు.
రెండో పద్ధతిలో అయితే, పేజీ యొక్క లింకును కూడా వాడవచ్చు. ఉదాహరణకు, "[[{{MediaWiki:Mainpage}}]]" కోసమైతే [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] అని ఇవ్వవచ్చు.',
+'exportall' => 'పేజీలన్నిటినీ ఎగుమతి చెయ్యి',
'exportcuronly' => 'ప్రస్తుత కూర్పు మాత్రమే, పూర్తి చరితం వద్దు',
'exportnohistory' => "----
'''గమనిక:''' ఈ ఫారాన్ని ఉపయోగించి పేజీలయొక్క పూర్తి చరిత్రను ఎగుమతి చేయడాన్ని సర్వరుపై వత్తిడి పెరిగిన కారణంగా ప్రస్తుతం నిలిపివేశారు.",
'allmessages-prefix' => 'ఉపసర్గ పై వడపోత:',
'allmessages-language' => 'భాష:',
'allmessages-filter-submit' => 'వెళ్ళు',
+'allmessages-filter-translate' => 'అనువదించు',
# Thumbnails
'thumbnail-more' => 'పెద్దది చెయ్యి',
'filemissing' => 'ఫైలు కనపడుటలేదు',
'thumbnail_error' => '$1: నఖచిత్రం తయారుచెయ్యడంలో లోపం జరిగింది',
+'thumbnail_error_remote' => '$1 నుండి వచ్చిన లోప సందేశం:
+$2',
'djvu_page_error' => 'DjVu పేజీ రేంజి దాటిపోయింది',
'djvu_no_xml' => 'DjVu ఫైలు కోసం XMLను తీసుకుని రాలేకపోయాను',
+'thumbnail-temp-create' => 'తాత్కాలిక థంబ్నెయిల్ ఫైలును సృష్టించలేకపోయాం',
+'thumbnail-dest-create' => 'థంబ్నెయిలును గమ్యస్థానంలో భద్రపరచలేకపోయాం',
'thumbnail_invalid_params' => 'నఖచిత్రాలకు సరయిన పారామీటర్లు లేవు',
'thumbnail_dest_directory' => 'గమ్యస్థానంలో డైరెక్టరీని సృష్టించలేకపోయాం',
'thumbnail_image-type' => 'ఈ బొమ్మ రకానికి మద్దతు లేదు',
'import-interwiki-templates' => 'అన్ని మూసలను ఉంచు',
'import-interwiki-submit' => 'దిగుమతించు',
'import-interwiki-namespace' => 'లక్ష్యిత నేంస్పేసు:',
+'import-interwiki-rootpage' => 'గమ్యస్థానపు మూలపు పేజీ (ఐచ్ఛికం):',
'import-upload-filename' => 'పైలుపేరు:',
'import-comment' => 'వ్యాఖ్య:',
'importtext' => '[[Special:Export|ఎగుమతి ఉపకరణాన్ని]] ఉపయోగించి, ఈ ఫైలుని మూల వికీ నుంచి ఎగుమతి చెయ్యండి.
'importuploaderrortemp' => 'దిగుమతి ఫైలు అప్లోడు ఫలించలేదు. ఒక తాత్కాలిక ఫోల్డరు కనిపించటం లేదు.',
'import-parse-failure' => 'దిగుమతి చేసుకుంటున్న XML విశ్లేషణ ఫలించలేదు',
'import-noarticle' => 'దిగుమతి చెయ్యాల్సిన పేజీ లేదు!',
-'import-nonewrevisions' => 'à°\85à°¨à±\8dని à°\95à±\82à°°à±\8dà°ªà±\81à°²à±\82 à°\97à°¤à°\82à°²à±\8bà°¨à±\87 దిà°\97à±\81మతయà±\8dయాయి.',
+'import-nonewrevisions' => 'à°\95à±\82à°°à±\8dà°ªà±\81à°²à±\87à°µà±\80 దిà°\97à±\81మతి à°\95ాలà±\87à°¦à±\81 (à°\85వనà±\8dà°¨à±\80 à°\88సరిà°\95à±\87 à°\89à°\82à°¡à°¿ à°\89à°\82డాలి, à°²à±\87దా à°²à±\8bపాల à°\95ారణà°\82à°\97à°¾ వదిలà±\86à°¯à±\8dయబడà±\8dడాయి).',
'xml-error-string' => '$1 $2వ లైనులో, వరుస $3 ($4వ బైటు): $5',
'import-upload' => 'XML డేటాను అప్లోడు చెయ్యి',
'import-token-mismatch' => 'సెషను భోగట్టా పోయింది. దయచేసి మళ్ళీ ప్రయత్నించండి.',
'import-invalid-interwiki' => 'మీరు చెప్పిన వికీనుండి దిగుమతి చేయలేము.',
+'import-error-edit' => 'పేజీ "$1" లో మార్పుచేర్పులు చేసే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-create' => 'పేజీ "$1" ను సృష్టించే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-interwiki' => 'పేజీ "$1" యొక్క పేరు బయటి లింకుల (అంతరవికీ) కోసం అట్టేపెట్టబడింది కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-special' => 'పేజీ "$1" ప్రత్యేక పేరుబరికి చెందినది. ఈ పేరుబరిలో పేజీలు సృష్టించే అనుమతి లేదు. అందుచేత దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-invalid' => 'పేజీ "$1" పేరు సరైనది కాదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-options-wrong' => 'తప్పు {{PLURAL:$2|ఐచ్ఛికం|ఐచ్ఛికాలు}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'ఇచ్చిన మూలపు పేజీ సరైన శీర్షిక కాదు.',
# Import log
'importlogpage' => 'దిగుమతుల చిట్టా',
# Info page
'pageinfo-title' => '"$1" గురించి సమాచారం',
+'pageinfo-not-current' => 'పాత కూర్పులకు సంబంధించి ఈ సమాచారాన్ని ఇవ్వడం అసాధ్యం, సారీ.',
'pageinfo-header-basic' => 'ప్రాథమిక సమాచారం',
'pageinfo-header-edits' => 'మార్పుల చరిత్ర',
+'pageinfo-header-restrictions' => 'పేజీ సంరక్షణ',
+'pageinfo-header-properties' => 'పేజీ లక్షణాలు',
+'pageinfo-display-title' => 'శీర్షిక చూపించు',
+'pageinfo-length' => 'పేజీ నిడివి (బైట్లలో)',
+'pageinfo-article-id' => 'పేజీ ఐడీ',
+'pageinfo-language' => 'పేజీ విషయపు భాష',
+'pageinfo-robot-index' => 'అనుమతించబడింది',
+'pageinfo-robot-noindex' => 'అనుమతించబడలేదు',
'pageinfo-views' => 'వీక్షణల సంఖ్య',
'pageinfo-watchers' => 'పేజీ వీక్షకుల సంఖ్య',
+'pageinfo-few-watchers' => '$1 {{PLURAL:$1|వీక్షకుడి|వీక్షకుల}} కంటే తక్కువ',
+'pageinfo-redirects-name' => 'ఈ పేజీకి ఉన్న దారిమార్పుల సంఖ్య',
+'pageinfo-subpages-name' => 'ఈ పేజీకి ఉన్న ఉపపేజీల సంఖ్య',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|దారిమార్పు|దారిమార్పులు}}; $3 {{PLURAL:$3|దారిమార్పు కానిది|దారిమార్పు కానివి}})',
+'pageinfo-firstuser' => 'పేజీ సృష్టికర్త',
+'pageinfo-firsttime' => 'పేజీని సృష్టించిన తేదీ',
+'pageinfo-lastuser' => 'ఇట్టీవలి మార్పుచేర్పుల కర్త',
+'pageinfo-lasttime' => 'చివరిసారిగా మార్పు చేసిన తేదీ',
'pageinfo-edits' => 'మొత్తం మార్పుల సంఖ్య',
+'pageinfo-recent-edits' => 'ఇటీవలి మార్పుల సంఖ్య (గత $1 లోపు)',
+'pageinfo-magic-words' => 'చమత్కార {{PLURAL:$1|పదం|పదాలు}} ($1)',
+'pageinfo-hidden-categories' => 'దాచిన {{PLURAL:$1|వర్గం|వర్గాలు}} ($1)',
+'pageinfo-templates' => 'ట్రాన్స్క్లూడు చేసిన {{PLURAL:$1|మూస|మూసలు}} ($1)',
+'pageinfo-transclusions' => '($1) తో {{PLURAL:$1|పేజీ|పేజీలు}} ట్రాన్స్క్లూడు చెయ్యబడ్డాయి',
'pageinfo-toolboxlink' => 'పేజీ సమాచారం',
+'pageinfo-redirectsto' => 'ఇక్కడికి దారిమార్పు:',
+'pageinfo-redirectsto-info' => 'సమాచారం',
'pageinfo-contentpage-yes' => 'అవును',
'pageinfo-protect-cascading-yes' => 'అవును',
'pageinfo-category-info' => 'వర్గపు సమాచారం',
'markedaspatrollederror' => 'నిఘాలో ఉన్నట్లుగా గుర్తించలేకున్నాం',
'markedaspatrollederrortext' => 'నిఘాలో ఉన్నట్లు గుర్తించేందుకుగాను, కూర్పును చూపించాలి.',
'markedaspatrollederror-noautopatrol' => 'మీరు చేసిన మార్పులను మీరే నిఘాలో పెట్టలేరు.',
+'markedaspatrollednotify' => '$1 లో చేసిన ఈ మార్పు పర్యవేక్షణలో ఉన్నట్టుగా గుర్తించబడింది.',
# Patrol log
'patrol-log-page' => 'నిఘా చిట్టా',
'file-info-png-looped' => 'పునరావృతమవుతుంది',
'file-info-png-repeat' => '{{PLURAL:$1|ఒకసారి|$1 సార్లు}} ఆడించారు',
'file-info-png-frames' => '$1 {{PLURAL:$1|ఫ్రేము|ఫ్రేములు}}',
+'file-no-thumb-animation' => '<strong>గమనిక: సాంకేతిక కారణాల వల్ల, ఈ ఫైలు యొక్క థంబ్నెయిళ్ళు యానిమేటు చెయ్యబడవు.</strong>',
+'file-no-thumb-animation-gif' => '<strong>గమనిక: సాంకేతిక కారణాల వల్ల, ఇలాంటి అధిక రిసొల్యూషన్ కలిగిన బొమ్మలు యానిమేటు చెయ్యబడవు.</strong>',
# Special:NewFiles
'newimages' => 'కొత్త ఫైళ్ళ కొలువు',
'exif-lens' => 'వాడిన కటకం',
'exif-serialnumber' => 'కెమేరా యొక్క సీరియల్ నంబర్',
'exif-cameraownername' => 'కేమెరా యజమాని',
+'exif-label' => 'సూచిక (లేబెల్)',
'exif-rating' => 'రేటింగు (5 కి గాను)',
'exif-rightscertificate' => 'హక్కుల నిర్వాహణ ధృవీకరణ పత్రం',
'exif-copyrighted' => 'కాపీహక్కుల స్థితి',
'htmlform-selectorother-other' => 'ఇతర',
'htmlform-no' => 'కాదు',
'htmlform-yes' => 'అవును',
+'htmlform-chosen-placeholder' => 'ఒక ఐచ్ఛికాన్ని ఎంచుకోండి',
# SQLite database support
'sqlite-has-fts' => '$1 పూర్తి-పాఠ్య అన్వేషణ తోడ్పాటుతో',
# New logging system
'logentry-delete-delete' => '$1 $3 పేజీని {{GENDER:$2|తొలగించారు}}',
+'logentry-delete-restore' => 'పేజీ $3 ని $1 {{GENDER:$2|పునస్థాపించారు}}',
+'logentry-delete-event' => '$3 లో {{PLURAL:$5|ఒక లాగ్ ఘటన|$5 లాగ్ ఘటనల}} యొక్క కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}: $4',
+'logentry-delete-revision' => 'పేజీ $3 లో {{PLURAL:$5|ఒక కూర్పు|$5 కూర్పుల}} యొక్క కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}: $4',
+'logentry-delete-event-legacy' => '$3 లో లాగ్ ఘటనల కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}',
+'logentry-delete-revision-legacy' => 'పేజీ $3 లో కూర్పుల కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}',
+'logentry-suppress-delete' => 'పేజీ $3 ని $1 {{GENDER:$2|అణచిపెట్టారు}}',
'revdelete-content-hid' => 'కంటెంట్ దాచబడింది',
'revdelete-summary-hid' => 'మార్పుల సారాంశాన్ని దాచారు',
'revdelete-uname-hid' => 'వాడుకరి పేరుని దాచారు',
'revdelete-restricted' => 'నిర్వాహకులకు ఆంక్షలు విధించాను',
'revdelete-unrestricted' => 'నిర్వాహకులకున్న ఆంక్షలను ఎత్తేశాను',
-'logentry-move-move' => '$1 $3 పేజీని $4కి తరలించారు',
-'logentry-move-move-noredirect' => '$1 $3 పేజీని $4కి దారిమార్పు లేకుండా తరలించారు',
-'logentry-move-move_redir' => '$1 $3 పేజీని $4కి దారిమార్పు ద్వారా తరలించారు',
-'logentry-move-move_redir-noredirect' => '$1 $3 పేజీని $4కి దారిమార్పు లేకుండా తరలించారు',
-'logentry-newusers-newusers' => '$1 వాడుకరి ఖాతాను సృష్టించారు',
-'logentry-newusers-create' => '$1 ఒక వాడుకరి ఖాతాను సృష్టించారు',
-'logentry-newusers-create2' => '$1 వాడుకరి ఖాతా $3ను సృష్టించారు',
-'logentry-newusers-autocreate' => '$1 ఖాతాను ఆటోమెటిగ్గా సృష్టించారు',
+'logentry-move-move' => '$1, పేజీ $3 ను $4 కు {{GENDER:$2|తరలించారు}}',
+'logentry-move-move-noredirect' => '$1, పేజీ $3 ను $4 కు దారిమార్పు లేకుండా {{GENDER:$2|తరలించారు}}',
+'logentry-move-move_redir' => '$1, పేజీ $3 ను $4 కు దారిమార్పు ద్వారా {{GENDER:$2|తరలించారు}}',
+'logentry-move-move_redir-noredirect' => '$1, పేజీ $3 ను $4 కు దారిమార్పు ద్వారా దారిమార్పును ఉంచకుండా {{GENDER:$2|తరలించారు}}',
+'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-create2' => '$1 వాడుకరి ఖాతా $3 ను {{GENDER:$2|సృష్టించారు}}',
+'logentry-newusers-byemail' => '$1 వాడుకరి ఖాతా $3 ను {{GENDER:$2|సృష్టించారు}}. సంకేతపదాన్ని ఈమెయిలులో పంపించాం',
+'logentry-newusers-autocreate' => 'వాడుకరి ఖాతా $1 ను ఆటోమేటిగ్గా {{GENDER:$2|సృష్టించారు}}',
+'logentry-rights-rights' => '$1, $3 యొక్క గుంపు సభ్యత్వాన్ని $4 నుండి $5 కు {{GENDER:$2|మార్చారు}}',
+'logentry-rights-rights-legacy' => '$1, $3 యొక్క గుంపు సభ్యత్వాన్ని {{GENDER:$2|మార్చారు}}',
+'logentry-rights-autopromote' => '$1, $4 నుండి $5 కు ఆటోమేటిగ్గా {{GENDER:$2|ప్రమోటు చెయ్యబడ్డారు}}',
'rightsnone' => '(ఏమీలేవు)',
# Feedback
+'feedback-bugornote' => 'ఏదైనా సాంకేతిక సమస్యను మీరు వివరించదలిస్తే [$1 లోపంపై ఫిర్యాదు చెయ్యండి].
+లేదంటే, కింద ఉన్న సులువైన ఫారాన్ని వాడండి. మీ వ్యాఖ్య మీ వాడుకరిపేరుతో సహా "[$3 $2]" పేజీలో చేర్చబడుతుంది.',
'feedback-subject' => 'విషయం:',
'feedback-message' => 'సందేశం:',
'feedback-cancel' => 'రద్దుచేయి',
'feedback-submit' => 'ప్రతిస్పందనను దాఖలుచేయి',
+'feedback-adding' => 'ఫీడ్బ్యాకును పేజీలోకి చేరుస్తున్నాం...',
'feedback-error2' => 'దోషము: సవరణ విఫలమైంది',
+'feedback-error3' => 'లోపం: API నుండి ప్రతిస్పందన లేదు',
'feedback-thanks' => 'కృతజ్ఞతలు! మీ ప్రతిస్పందనను “[$2 $1]” పేజీలో చేర్చాం.',
'feedback-close' => 'పూర్తయ్యింది',
'feedback-bugcheck' => 'అద్భుతం! ఇది ఇప్పటికే [$1 తెలిసిన బగ్గుల]లో లేదని సరిచూసుకోండి.',
# API errors
'api-error-badaccess-groups' => 'ఈ వికీ లోనికి దస్త్రాలను ఎక్కించే అనుమతి మీకు లేదు.',
+'api-error-badtoken' => 'అంతర్గత లోపం: చెడు టోకెన్.',
+'api-error-copyuploaddisabled' => 'URL ద్వారా ఎక్కించడం ఈ సర్వరులో అశక్తం చెయ్యబడింది.',
+'api-error-duplicate' => 'ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|[$2 మరో ఫైలు] ఉంది|[$2 ఇతర ఫైళ్ళు] ఉన్నాయి}}.',
+'api-error-duplicate-archive' => 'ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|[$2 మరో ఫైలు] ఉండేది|[$2 ఇతర ఫైళ్ళు] ఉండేవి}}. అయితే {{PLURAL:$1|అది తొలగించబడింది|అవి తొలగించబడ్డాయి}}.',
'api-error-duplicate-archive-popup-title' => 'నకిలీ {{PLURAL:$1|దస్త్రాన్ని|దస్త్రాలను}} ఇప్పటికే తొలగించారు.',
'api-error-duplicate-popup-title' => 'నకిలీ {{PLURAL:$1|దస్త్రం|దస్త్రాలు}}.',
'api-error-empty-file' => 'మీరు దాఖలుచేసిన ఫైల్ ఖాళీది.',
'api-error-emptypage' => 'కొత్త మరియు ఖాళీ పేజీలను సృష్టించడానికి అనుమతి లేదు.',
+'api-error-fetchfileerror' => 'అంతర్గత లోపం: ఈ ఫైలును తేవడంలో ఏదో తప్పు జరిగింది.',
+'api-error-fileexists-forbidden' => '"$1" పేరుతో ఓ ఫైలు ఈసరికే ఉంది. దాన్ని తిరగరాయడం కుదరదు.',
+'api-error-fileexists-shared-forbidden' => '"$1" పేరుతో ఓ ఫైలు ఈసరికే ఈ సహ ఫైలు ఖజానా (షేర్డ్ ఫైల్ రిపాజిటరీ)లో ఉంది. దాన్ని తిరగరాయడం కుదరదు.',
'api-error-file-too-large' => 'మీరు సమర్పించిన దస్త్రం చాలా పెద్దగా ఉంది.',
'api-error-filename-tooshort' => 'దస్త్రపు పేరు మరీ చిన్నగా ఉంది.',
'api-error-filetype-banned' => 'ఈ రకపు దస్త్రాలని నిషేధించారు.',
-'api-error-filetype-banned-type' => '$1 {{PLURAL:$4|అనేది అనుమతించబడిన ఫైలు రకం కాదు|అనేవి అనుమతించబడిన ఫైలు రకాలు కాదు}}. అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}} $2.',
+'api-error-filetype-banned-type' => '$1, అనుమతించబడిన {{PLURAL:$4|ఫైలు రకం కాదు|ఫైలు రకాలు కాదు}}. అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}}: $2.',
+'api-error-filetype-missing' => 'ఫైలుపేరులో ఓ ఎక్స్టెన్షను లేదు.',
'api-error-http' => 'అంతర్గత దోషము: సేవకానికి అనుసంధానమవలేకపోతున్నది.',
'api-error-illegal-filename' => 'ఆ పైల్ పేరు అనుమతించబడదు.',
'api-error-invalid-file-key' => 'అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.',
'duration-millennia' => '$1 {{PLURAL:$1|సహస్రాబ్దం|సహస్రాబ్దాలు}}',
# Limit report
+'limitreport-cputime' => 'CPU సమయం వినియోగం',
'limitreport-cputime-value' => '$1 {{PLURAL:$1|క్షణం|క్షణాలు}}',
+'limitreport-walltime' => 'నిజ సమయం వినియోగం',
'limitreport-walltime-value' => '$1 {{PLURAL:$1|క్షణం|క్షణాలు}}',
+'limitreport-postexpandincludesize-value' => '$1/$2 {{PLURAL:$2|బైట్|బైట్లు}}',
'limitreport-templateargumentsize-value' => '$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}',
# Special:ExpandTemplates
'invalid-content-data' => 'مەزمۇن سانلىق مەلۇماتى ئىناۋەتسىز',
'content-not-allowed-here' => '[[$2]] بەتتە "$1" مەزمۇنغا يول قويۇلمايدۇ',
'editwarning-warning' => 'بەتتىن ئايرىلغاندا بەلكىم بارلىق تەھرىرلىگىنىڭىز بېكار بولۇپ كېتىشى مۇمكىن.
-ئەگەر تىزىمغا كىرسىڭىز، مايىللىق بېتىڭىزنىڭ «تەھرىر» بۆلىكىدە، بۇ ئەسكەرتمىنى ئىناۋەتسىز قىلالايسىز.',
+ئەگەر تىزىمغا كىرسىڭىز، مايىللىق بېتىڭىزنىڭ «{{int:prefs-editing}}» بۆلىكىدە، بۇ ئەسكەرتمىنى ئىناۋەتسىز قىلالايسىز.',
# Content models
'content-model-wikitext' => 'ۋىكىتېكىست',
'invalid-content-data' => 'Неприпустимі дані',
'content-not-allowed-here' => 'Вміст «$1» недопустимий на сторінці [[$2]]',
'editwarning-warning' => 'Перехід на іншу сторінку призведе до втрати ваших змін.
-Якщо ви ввійшли до системи, то ви можете відключити це попередження в розділі «Редагування» ваших налаштувань.',
+Якщо ви ввійшли до системи, то ви можете відключити це попередження в розділі "{{int:prefs-editing}}" ваших налаштувань.',
'editpage-notsupportedcontentformat-title' => 'Непідтримуваний формат вмісту',
'editpage-notsupportedcontentformat-text' => 'Формат вмісту $1 не підтримується моделлю вмісту $2.',
'showhideselectedversions' => 'Показати/приховати обрані версії',
'editundo' => 'скасувати',
'diff-empty' => '(Немає відмінностей)',
+'diff-multi-sameuser' => '(не {{PLURAL:$1|показано одну проміжну версію|показані $1 проміжні версії|показано $1 проміжних версій}} цього учасника)',
+'diff-multi-otherusers' => '(не {{PLURAL:$1|показана одна проміжна версія|показано $1 проміжні версії|показані $1 проміжних версій}} {{PLURAL:$2|ще одного учасника|$2 учасників}})',
'diff-multi-manyusers' => '({{PLURAL:$1|не показана $1 проміжна версія|не показані $1 проміжні версії|не показано $1 проміжних версій}}, зроблених більш, ніж {{PLURAL:$2|1=$1 користувачем|$2 користувачами}})',
'difference-missing-revision' => '{{PLURAL:$2|$2 версія|$2 версії|$2 версій}} для цього порівняння ($1) не {{PLURAL:$2|1=знайдена|знайдені}}.
'shown-title' => 'Показувати $1 {{PLURAL:$1|запис|записи|записів}} на сторінці',
'viewprevnext' => 'Переглянути ($1 {{int:pipe-separator}} $2) ($3).',
'searchmenu-exists' => "'''У цій вікі є сторінка з назвою «[[:$1]]»'''",
-'searchmenu-new' => "'''Створити сторінку «[[:$1]]» у цій вікі!'''",
+'searchmenu-new' => '<strong>Створити сторінку «[[:$1]]» у цьому вікі-проекті!</strong>
+{{PLURAL:$2|0=|Див. також сторінку, знайдену по результатами вашого пошуку.|Див. також знайдені результати пошуку.}}',
'searchprofile-articles' => 'Статті',
'searchprofile-project' => 'Сторінки довідки і проекту',
'searchprofile-images' => 'Мультимедіа',
'tog-editondblclick' => 'Sichqoncha tugmasini ikki marta bosish orqali tahrirlashni boshlash',
'tog-editsectiononrightclick' => 'Boʻlim sarlavhasiga sichqonchaning oʻng tugmasi bilan bosib tahrirlashni boshlash',
'tog-rememberpassword' => 'Hisob ma’lumotlarim ushbu brauzerda eslab qolinsin (ko‘pi bilan $1 kunga)',
-'tog-watchcreations' => 'Men yaratgan sahifalarni va yuklagan fayllarni kuzatuv roʻyxatimga qoʻsh',
-'tog-watchdefault' => 'Men tahrirlagan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
-'tog-watchmoves' => 'Men koʻchirgan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
+'tog-watchcreations' => 'Men yaratgan sahifalar va yuklagan fayllar kuzatuv roʻyxatimga qoʻshilsin',
+'tog-watchdefault' => 'Men tahrirlagan sahifa va fayllar kuzatuv roʻyxatimga qoʻshilsin',
+'tog-watchmoves' => 'Men nomini koʻchirgan sahifa va fayllar kuzatuv roʻyxatimga qoʻshilsin',
'tog-watchdeletion' => 'Men oʻchirgan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
'tog-minordefault' => 'Sukut boʻyicha barcha tahrirlarimni «kichik tahrir» etib belgilash',
-'tog-previewontop' => 'Tahrir oynasi tepasida koʻrib chiqish',
-'tog-previewonfirst' => 'Tahrirlashga oʻtiboq koʻrib chiqishni boshlash',
+'tog-previewontop' => 'Koʻrib chiqish imkoniyati tahrir oynasi tepasida boʻlsin',
+'tog-previewonfirst' => 'Tahrirlashga oʻtgandayoq koʻrib chiqishni boshlash',
'tog-enotifwatchlistpages' => 'Kuzatuv roʻyxatimdagi sahifa yoki fayllar oʻzgartirilsa, menga bu haqda xat yuborilsin',
'tog-enotifusertalkpages' => 'Munozara sahifam oʻzgartirilsa, menga bu haqda xat yuborilsin',
'tog-enotifminoredits' => 'Kichik tahrir qilinsa ham e-pochtamga bu haqda xat yuborilsin',
'tog-noconvertlink' => 'Sarlavhani oʻzgartirish havolasini oʻchirib qoʻyish',
'tog-norollbackdiff' => 'Tahrir qaytarilganda, versiyalar taqqosi koʻrsatilmasin',
'tog-useeditwarning' => 'Kiritgan oʻzgarishlarimni saqlamay sahifadan chiqib ketayotganim haqida ogohlantirilsin',
+'tog-prefershttps' => 'Doim himoyalangan holda kirish',
'underline-always' => 'Har doim',
'underline-never' => 'Hech qachon',
'viewsource' => 'Manbasini koʻrish',
'viewsource-title' => '$1 sahifasining manbasini koʻrish',
'actionthrottled' => 'Tezlik cheklovi',
-'protectedpagetext' => 'Bu sahifa tahrirlash va boshqa oʻzgartirishlar kiritishdan himoyalangan.',
+'protectedpagetext' => 'Bu sahifa tahrirlash va boshqa oʻzgarishlar kiritishdan himoyalangan.',
'viewsourcetext' => 'Siz bu sahifaning manbasini koʻrishingiz va uni nusxasini olishingiz mumkin:',
+'protectedinterface' => 'Ushbu sahifada dasturiy taʼminot interfeysi xabari mavjud. Bezoriliklardan saqlash uchun uni oʻzgartirish taʼqiqlangan.
+Ushbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.',
'editinginterface' => "'''Diqqat:''' Siz dasturiy taʼminot interfeysi matni mavjud boʻlgan sahifani tahrirlamoqdasiz.
Uning oʻzgartirilishi ushbu vikidagi boshqa foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.
Ushbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
# Change password dialog
'changepassword' => 'Maxfiy soʻzni oʻzgartirish',
-'resetpass_header' => "Hisob mahfiy so'zini o'zgartirish",
+'resetpass_header' => 'Maxfiy soʻzni oʻzgartirish',
'oldpassword' => "Eski mahfiy so'z:",
'newpassword' => "Yangi mahfiy so'z:",
'retypenew' => 'Yangi mahfiy soʻzni qayta tering:',
'headline_tip' => '2-darajadagi sarlavha',
'nowiki_sample' => 'Bu yerga formatlash zarur boʻlmagan matnni qoʻying',
'nowiki_tip' => "Viki-formatlashga e'tibor qilmaslik",
-'image_tip' => 'Qoʻshilgan tasvir',
+'image_tip' => 'Fayl oʻrnatish',
'media_tip' => 'Faylga havola',
'sig_tip' => 'Imzoingiz va sana',
'hr_tip' => "Yotiq (gorizontal) chiziq (ko'p ishlatmang)",
'watchthis' => 'Sahifani kuzatish',
'savearticle' => 'Saqlash',
'preview' => 'Ko‘rib chiqish',
-'showpreview' => 'Ko‘rib chiqish',
+'showpreview' => 'Koʻrib chiqish',
'showlivepreview' => 'Tezkor koʻrib chiqish',
'showdiff' => 'O‘zgarishlarni ko‘rsatish',
'anoneditwarning' => "'''Diqqat:''' Siz tizimga kirmagansiz. Ushbu sahifa tarixida Sizning IP manzilingiz yozib qolinadi.",
'search-interwiki-default' => '$1 natijalar:',
'search-interwiki-more' => '(yana)',
'search-relatedarticle' => "Bog'liq",
-'searcheverything-enable' => 'Barcha nomfazolarda qidir',
+'searcheverything-enable' => 'Barcha nomfazolardan qidirish',
'searchrelated' => 'bogʻlangan',
'searchall' => 'barchasi',
'showingresults' => "Quyida №'''$2'''dan boshlab {{PLURAL:$1|'''bitta''' natija|'''$1''' ta natija}} koʻrsatilgan.",
'prefs-rc' => 'Yangi o‘zgartirishlar',
'prefs-watchlist' => 'Kuzatuv roʻyxati',
'prefs-watchlist-days' => 'Kunlar soni:',
-'prefs-watchlist-days-max' => 'Eng ko‘pi bilan $1 {{PLURAL:$1|kun}}',
-'prefs-watchlist-edits-max' => 'Eng katta son: 1000',
+'prefs-watchlist-days-max' => 'Maksimum $1 kun',
+'prefs-watchlist-edits' => 'Kengaytirilgan kuzatuv roʻyxatingizda koʻrsatiladigan oʻzgarishlar soni:',
+'prefs-watchlist-edits-max' => 'Maksimum: 1000',
+'prefs-watchlist-token' => 'Kuzatuv roʻyxatingiz tokeni:',
'prefs-misc' => 'Boshqa moslamalar',
'prefs-resetpass' => 'Maxfiy soʻzni oʻzgartirish',
'prefs-changeemail' => 'Elektron pochta manzilini oʻzgartirish',
'rows' => 'Qatorlar soni:',
'columns' => 'Ustunlar soni:',
'searchresultshead' => 'Qidiruv',
-'stub-threshold' => '<a href="#" class="stub">Chala maqolalarga ishorat</a> keltirish uchun pastki chegara (baytlarda):',
+'stub-threshold' => '[[Special:ShortPages|Chala maqolalarga]] ishorat keltirish uchun pastki chegara:',
'stub-threshold-disabled' => 'Oʻchirib qoʻyilgan',
'recentchangesdays' => 'Necha kunlik tahrirlar koʻrsatiladi:',
-'recentchangesdays-max' => 'Eng koʻpi — $1 kun',
+'recentchangesdays-max' => 'Maksimum $1 kun',
'recentchangescount' => 'Sukut boʻyicha koʻrsatiladigan tahrirlar soni:',
-'prefs-help-recentchangescount' => 'Yangi oʻzgarishlar, tarix va qaydlar uchun.',
+'prefs-help-recentchangescount' => 'Yangi oʻzgarishlar, sahifalar tarixi va qaydlar uchun',
+'prefs-help-watchlist-token2' => 'Bu kuzatuv roʻyxatingizning veb-kanali uchun maxfiy kalit kodi.
+Bu kodni biladigan har kim sizning kuzatuv roʻyxatingizni koʻrishi mumkin, shuning uchun boshqalarga uni oshkor qilmang. [[Special:ResetTokens|Tokenni yangilash]].',
'savedprefs' => 'Sizning moslamalaringiz saqlandi.',
'timezonelegend' => 'Vaqt mintaqangiz:',
'localtime' => 'Mahalliy vaqt:',
'timezoneuseserverdefault' => 'Server moslamalaridan foydalanish ($1)',
-'timezoneuseoffset' => "Boshqa (siljishni ko'rsating)",
+'timezoneuseoffset' => 'Boshqa (siljishni koʻrsating)',
'servertime' => 'Server vaqti:',
'guesstimezone' => "Brauzerdan to'ldirish",
'timezoneregion-africa' => 'Afrika',
'upload' => 'Fayl yuklash',
'uploadbtn' => 'Fayl yuklash',
'uploaderror' => 'Yuklashda xatolik',
+'upload-recreate-warning' => '<strong>Diqqat: bunday nomli fayl avval yoʻqotilgan yoki koʻchirilgan.</strong>
+
+Quyida bu sahifaga oid yoʻqotish va koʻchirish qaydlari keltirilgan:',
+'upload-permitted' => 'Yuklash mumkin fayl turlari: $1.',
'uploadlogpage' => 'Yuklash qaydlari',
'filename' => 'Fayl nomi',
'filedesc' => 'Qisqa izoh',
'filestatus' => 'Tarqatish shartlari:',
'filesource' => 'Manba:',
'uploadedfiles' => 'Yuklangan fayllar',
+'ignorewarnings' => 'Ogohlantirishlarga eʼtibor qilma',
'uploadedimage' => '"[[$1]]"ni yukladi',
'overwroteimage' => '"[[$1]]"ning yangi versiyasini yukladi',
+'upload-source' => 'Yuklanayotgan fayl',
+'sourcefilename' => 'Fayl nomi:',
+'destfilename' => 'Fayl nomi:',
+'upload-maxfilesize' => 'Faylning maksimal oʻlchami: $1',
+'upload-description' => 'Fayl tavsifi',
+'upload-options' => 'Yuklash moslamalari',
+'watchthisupload' => 'Bu faylni kuzatish',
'license' => 'Litsenziyalash:',
'license-header' => 'Litsenziyalash',
+'upload_source_file' => '(kompyuteringizdagi fayl)',
# Special:ListFiles
'listfiles-summary' => 'Ushbu maxsus sahifada barcha yuklangan fayllar koʻrsatilgan.',
'uncategorizedcategories' => 'Turkumlashtirilmagan turkumlar',
'uncategorizedimages' => 'Turkumlashtirilmagan fayllar',
'uncategorizedtemplates' => 'Turkumlashtirilmagan andozalar',
-'unusedcategories' => 'Ishlatilinmagan turkumlar',
+'unusedcategories' => 'Ishlatilmayotgan turkumlar',
'unusedimages' => 'Ishlatilinmagan fayllar',
'wantedcategories' => 'Talab qilinayotgan turkumlar',
'mostcategories' => 'Eng koʻp turkumli sahifalar',
# Special:Categories
'categories' => 'Turkumlar',
-'categoriespagetext' => 'The following {{PLURAL:$1|category contains|categories contain}} pages or media.
-[[Special:UnusedCategories|Unused categories]] are not shown here.
-Also see [[Special:WantedCategories|wanted categories]].',
+'categoriespagetext' => 'Quyidagi {{PLURAL:$1|turkumda|turkumlarda}} sahifa yoki media-fayllar mavjud.
+[[Special:UnusedCategories|Ishlatilmayotgan turkumlar]] bu yerda koʻrsatilmaydi.
+Shuningdek qarang: [[Special:WantedCategories|talab qilinayotgan turkumlar]].',
'categoriesfrom' => 'Quyidagidan boshlanuvchi turkumlarni koʻrsatish:',
'special-categories-sort-count' => 'miqdori bo‘yicha saralash',
'special-categories-sort-abc' => 'alifbo bo‘yicha saralash',
'api-error-unknown-code' => 'Noaniq xato: "$1".',
'api-error-unknownerror' => 'Noaniq xato: "$1".',
+# Limit report
+'limitreport-title' => 'Tahlillagich maʼlumotlari:',
+
);
'invalid-content-data' => 'Dữ liệu nội dung không hợp lệ',
'content-not-allowed-here' => 'Không cho phép đưa nội dung “$1” vào trang [[$2]]',
'editwarning-warning' => 'Rời khỏi trang này sẽ khiến bạn mất các sửa đổi đã thực hiện.
-Nếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “Sửa đổi” trong tùy chọn cá nhân.',
+Nếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “{{int:prefs-editing}}” trong tùy chọn cá nhân.',
'editpage-notsupportedcontentformat-title' => 'Không hỗ trợ định dạng nội dung',
'editpage-notsupportedcontentformat-text' => 'Mô hình nội dung $2 không hỗ trợ định dạng nội dung $1.',
'undo-success' => 'Các sửa đổi có thể được lùi lại. Xin hãy kiểm tra phần so sánh bên dưới để xác nhận lại những gì bạn muốn làm, sau đó lưu thay đổi ở dưới để hoàn tất việc lùi lại sửa đổi.',
'undo-failure' => 'Sửa đổi không thể phục hồi vì đã có những sửa đổi mới ở sau.',
'undo-norev' => 'Sửa đổi không thể hồi phục vì nó không tồn tại hoặc đã bị xóa.',
+'undo-nochange' => 'Hình như sửa đổi này đã được lùi lại rồi.',
'undo-summary' => 'Đã lùi lại sửa đổi $1 của [[Special:Contributions/$2|$2]] ([[User talk:$2|Thảo luận]])',
'undo-summary-username-hidden' => 'Đã lùi lại sửa đổi $1 của một người dùng ẩn',
'showhideselectedversions' => 'ווײַזן/באַהאַלטן געקליבענע רעוויזיעס',
'editundo' => 'אַנולירן',
'diff-empty' => '(קיין אונטערשייד)',
+'diff-multi-otherusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון {{PLURAL:$2|איין אנדער באַניצער|$2 באַניצער}} נישט געוויזן.)',
'diff-multi-manyusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון מער ווי {{PLURAL:$2|איין באַניצער|$2 באַניצער}} נישט געוויזן.)',
'difference-missing-revision' => '{{PLURAL:$2|איין ווערסיע|$2 ווערסיעס}} פון דעם דיפערענץ ($1) {{PLURAL:$2|האט}} מען נישט געטראפן.
'shown-title' => 'ווײַזן $1 {{PLURAL:$1|רעזולטאַט| רעזולטאַטן}} אויף א בלאַט',
'viewprevnext' => 'קוקט אויף ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''ס'איז פֿאַראַן א בלאַט מיטן נאמען \"[[:\$1]]\" אין דער וויקי'''",
-'searchmenu-new' => "'''באַשאַפֿן דעם בלאַט \"[[:\$1]]\" אויף דער וויקי'''",
+'searchmenu-new' => '<strong>באַשאַפֿן דעם בלאַט "[[:$1]]" אויף דער וויקי!</strong> {{PLURAL:$2|0=|זעט אויך דעם בלאט געפֿונען מיט אײַער זוך.|זעט אויך די זוך רעזולטאטן געפֿונען.}}',
'searchprofile-articles' => 'אינהאלט בלעטער',
'searchprofile-project' => 'הילף און פראיעקט בלעטער',
'searchprofile-images' => 'מולטימעדיע',
אַ פראוויזארישער טעקע־האלטער פֿעלט.',
'import-parse-failure' => 'פֿעלער בײַם אימפארטירן XML',
'import-noarticle' => 'נישטא קיין בלאט צו אימפארטירן!',
-'import-nonewrevisions' => '×\90Ö·×\9c×¢ רע×\95×\95×\99×\96×\99עס ש×\95×\99×\9f ×\90×\99×\9eפ×\90ר×\98×\99ר×\98.',
+'import-nonewrevisions' => 'ק×\99×\99×\9f רע×\95×\95×\99×\96×\99עס × ×\99ש×\98 ×\90×\99×\9eפ×\90ר×\98×\99ר×\98 (×\90×\93ער ×\90×\9c×¢ ש×\95×\99×\9f ×\93×\90, ×\90×\93ער ×\90×\99×\91ער×\92×¢×\94×\99פ×\98 צ×\95×\9c×\99×\91 ×\92רײַ×\96×\9f).',
'xml-error-string' => '$1 בײַ שורה $2, זייל $3 (בייט $4): $5',
'import-upload' => 'אַרויפֿלאָדן XML דאַטן',
'import-token-mismatch' => 'אָנווער פון סעסיע דאַטן.
'content-failed-to-parse' => '未能将 $2 内容转换为 $1:$3',
'invalid-content-data' => '无效的内容数据',
'content-not-allowed-here' => '[[$2]]页面上不允许“$1”内容',
-'editwarning-warning' => '离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“编辑”部分停用该警告。',
+'editwarning-warning' => '离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“{{int:prefs-editing}}”部分停用该警告。',
'editpage-notsupportedcontentformat-title' => '内容格式尚不支持',
'editpage-notsupportedcontentformat-text' => '内容模型$2尚不支持内容格式$1。',
'newsectionsummary' => '/* $1 */ 新段落',
'rc-enhanced-expand' => '显示细节',
'rc-enhanced-hide' => '隐藏细节',
-'rc-old-title' => '最初被创建为" $1 "',
+'rc-old-title' => '最初创建为“$1”',
# Recent changes linked
'recentchangeslinked' => '相关更改',
--- /dev/null
+<?php
+/**
+ * Benchmark script for parse operations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Tim Starling <tstarling@wikimedia.org>
+ * @ingroup Benchmark
+ */
+
+require __DIR__ . '/../Maintenance.php';
+
+/**
+ * Maintenance script to benchmark how long it takes to parse a given title at an optionally
+ * specified timestamp
+ *
+ * @since 1.23
+ */
+class BenchmarkParse extends Maintenance {
+ /** @var string MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS) */
+ private $templateTimestamp = null;
+
+ /** @var array Cache that maps a Title DB key to revision ID for the requested timestamp */
+ private $idCache = array();
+
+ function __construct() {
+ parent::__construct();
+ $this->addDescription( 'Benchmark parse operation' );
+ $this->addArg( 'title', 'The name of the page to parse' );
+ $this->addOption( 'cold', 'Don\'t repeat the parse operation to warm the cache' );
+ $this->addOption( 'page-time',
+ 'Use the version of the page which was current at the given time',
+ false, true );
+ $this->addOption( 'tpl-time',
+ 'Use templates which were current at the given time (except that moves and ' .
+ 'deletes are not handled properly)',
+ false, true );
+ }
+
+ function execute() {
+ if ( $this->hasOption( 'tpl-time' ) ) {
+ $this->templateTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'tpl-time' ) ) );
+ Hooks::register( 'BeforeParserFetchTemplateAndtitle', array( $this, 'onFetchTemplate' ) );
+ }
+
+ $title = Title::newFromText( $this->getArg() );
+ if ( !$title ) {
+ $this->error( "Invalid title" );
+ exit( 1 );
+ }
+
+ if ( $this->hasOption( 'page-time' ) ) {
+ $pageTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'page-time' ) ) );
+ $id = $this->getRevIdForTime( $title, $pageTimestamp );
+ if ( !$id ) {
+ $this->error( "The page did not exist at that time" );
+ exit( 1 );
+ }
+
+ $revision = Revision::newFromId( $id );
+ } else {
+ $revision = Revision::newFromTitle( $title );
+ }
+
+ if ( !$revision ) {
+ $this->error( "Unable to load revision, incorrect title?" );
+ exit( 1 );
+ }
+
+ if ( !$this->hasOption( 'cold' ) ) {
+ $this->runParser( $revision );
+ }
+
+ $startUsage = getrusage();
+ $startTime = microtime( true );
+ $this->runParser( $revision );
+ $endUsage = getrusage();
+ $endTime = microtime( true );
+
+ printf( "CPU time = %.3f s, wall clock time = %.3f s\n",
+ // CPU time
+ $endUsage['ru_utime.tv_sec'] + $endUsage['ru_utime.tv_usec'] * 1e-6
+ - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6,
+ // Wall clock time
+ $endTime - $startTime );
+ }
+
+ /**
+ * Fetch the ID of the revision of a Title that occurred
+ *
+ * @param Title $title
+ * @param string $timestamp
+ * @return bool|string Revision ID, or false if not found or error
+ */
+ function getRevIdForTime( Title $title, $timestamp ) {
+ $dbr = wfGetDB( DB_SLAVE );
+
+ $id = $dbr->selectField(
+ array( 'revision', 'page' ),
+ 'rev_id',
+ array(
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDBkey(),
+ 'rev_timestamp <= ' . $dbr->addQuotes( $timestamp )
+ ),
+ __METHOD__,
+ array( 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ),
+ array( 'revision' => array( 'INNER JOIN', 'rev_page=page_id' ) )
+ );
+
+ return $id;
+ }
+
+ /**
+ * Parse the text from a given Revision
+ *
+ * @param Revision $revision
+ */
+ function runParser( Revision $revision ) {
+ $content = $revision->getContent();
+ $content->getParserOutput( $revision->getTitle(), $revision->getId() );
+ }
+
+ /**
+ * Hook into the parser's revision ID fetcher. Make sure that the parser only
+ * uses revisions around the specified timestamp.
+ *
+ * @param Parser $parser
+ * @param Title $title
+ * @param bool &$skip
+ * @param string|bool &$id
+ * @return bool
+ */
+ function onFetchTemplate( Parser $parser, Title $title, &$skip, &$id ) {
+ $pdbk = $title->getPrefixedDBkey();
+ if ( !isset( $this->idCache[$pdbk] ) ) {
+ $proposedId = $this->getRevIdForTime( $title, $this->templateTimestamp );
+ $this->idCache[$pdbk] = $proposedId;
+ }
+ if ( $this->idCache[$pdbk] !== false ) {
+ $id = $this->idCache[$pdbk];
+ }
+
+ return true;
+ }
+}
+
+$maintClass = 'BenchmarkParse';
+require RUN_MAINTENANCE_IF_MAIN;
* @author Antoine Musso <hashar@free.fr>
*/
-define( 'MW_SETUP_NO_CACHE', 1 );
-define( 'MW_SETUP_NO_CONTEXT', 1 );
require_once __DIR__ . '/Maintenance.php';
/**
"mw.language*",
"mw.cldr"
]
+ },
+ {
+ "name": "Page",
+ "classes": [
+ "mw.page*"
+ ]
}
]
},
"--": [
"./external.js",
"../../resources/mediawiki/mediawiki.js",
+ "../../resources/mediawiki/mediawiki.htmlform.js",
"../../resources/mediawiki/mediawiki.log.js",
"../../resources/mediawiki/mediawiki.util.js",
"../../resources/mediawiki/mediawiki.Title.js",
"../../resources/mediawiki.action/mediawiki.action.edit.js",
"../../resources/mediawiki.action/mediawiki.action.view.postEdit.js",
"../../resources/mediawiki.page/mediawiki.page.startup.js",
+ "../../resources/mediawiki.page/mediawiki.page.watch.ajax.js",
"../../resources/mediawiki.api",
"../../resources/mediawiki.language",
"../../resources/jquery/jquery.localize.js",
'undo-success',
'undo-failure',
'undo-norev',
+ 'undo-nochange',
'undo-summary',
'undo-summary-username-hidden',
),
'searchrelated',
'searchall',
'showingresults',
+ 'showingresultsinrange',
'showingresultsnum',
'showingresultsheader',
'search-nonefound',
parent::__construct();
$this->addOption( 'list', 'List special page names' );
$this->addOption( 'only', 'Only update "page"; case sensitive, ' .
- 'check correct case by calling this script with --list or on ' .
- 'includes/QueryPage.php. Ex: --only=BrokenRedirects', false, true );
+ 'check correct case by calling this script with --list or on ' .
+ 'includes/QueryPage.php. Ex: --only=BrokenRedirects', false, true );
$this->addOption( 'override', 'Also update pages that have updates disabled' );
}
public function execute() {
global $IP, $wgQueryPages, $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
- if ( !$this->hasOption( 'list' ) && !$this->hasOption( 'only' ) ) {
- $this->doSpecialPageCacheUpdates();
- }
$dbw = wfGetDB( DB_MASTER );
+ $this->doSpecialPageCacheUpdates( $dbw );
+
// This is needed to initialise $wgQueryPages
require_once "$IP/includes/QueryPage.php";
# --list : just show the name of pages
if ( $this->hasOption( 'list' ) ) {
- $this->output( "$special\n" );
+ $this->output( "$special [QueryPage]\n" );
continue;
}
- if ( !$this->hasOption( 'override' ) && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate ) ) {
- $this->output( sprintf( "%-30s disabled\n", $special ) );
+ if ( !$this->hasOption( 'override' )
+ && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate ) )
+ {
+ $this->output( sprintf( "%-30s [QueryPage] disabled\n", $special ) );
continue;
}
}
if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $queryPage->getName() ) {
- $this->output( sprintf( '%-30s ', $special ) );
+ $this->output( sprintf( '%-30s [QueryPage] ', $special ) );
if ( $queryPage->isExpensive() ) {
$t1 = explode( ' ', microtime() );
# Do the query
}
}
- public function doSpecialPageCacheUpdates() {
+ public function doSpecialPageCacheUpdates( $dbw ) {
global $wgSpecialPageCacheUpdates;
- $dbw = wfGetDB( DB_MASTER );
foreach ( $wgSpecialPageCacheUpdates as $special => $call ) {
- if ( !is_callable( $call ) ) {
- $this->error( "Uncallable function $call!" );
+ # --list : just show the name of pages
+ if ( $this->hasOption( 'list' ) ) {
+ $this->output( "$special [callback]\n" );
continue;
}
- $this->output( sprintf( '%-30s ', $special ) );
- $t1 = explode( ' ', microtime() );
- call_user_func( $call, $dbw );
- $t2 = explode( ' ', microtime() );
- $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] );
- $hours = intval( $elapsed / 3600 );
- $minutes = intval( $elapsed % 3600 / 60 );
- $seconds = $elapsed - $hours * 3600 - $minutes * 60;
- if ( $hours ) {
- $this->output( $hours . 'h ' );
- }
- if ( $minutes ) {
- $this->output( $minutes . 'm ' );
+
+ if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $special ) {
+ if ( !is_callable( $call ) ) {
+ $this->error( "Uncallable function $call!" );
+ continue;
+ }
+ $this->output( sprintf( '%-30s [callback] ', $special ) );
+ $t1 = explode( ' ', microtime() );
+ call_user_func( $call, $dbw );
+ $t2 = explode( ' ', microtime() );
+
+ $this->output( "completed in " );
+ $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] );
+ $hours = intval( $elapsed / 3600 );
+ $minutes = intval( $elapsed % 3600 / 60 );
+ $seconds = $elapsed - $hours * 3600 - $minutes * 60;
+ if ( $hours ) {
+ $this->output( $hours . 'h ' );
+ }
+ if ( $minutes ) {
+ $this->output( $minutes . 'm ' );
+ }
+ $this->output( sprintf( "%.2fs\n", $seconds ) );
+ # Wait for the slave to catch up
+ wfWaitForSlaves();
}
- $this->output( sprintf( "completed in %.2fs\n", $seconds ) );
- # Wait for the slave to catch up
- wfWaitForSlaves();
}
}
}
'remoteBasePath' => $GLOBALS['wgStylePath'],
'localBasePath' => $GLOBALS['wgStyleDirectory'],
),
- // FIXME: Remove in favour of skins.monobook.styles when cache expires
- 'skins.monobook' => array(
- 'styles' => array(
- 'common/commonElements.css' => array( 'media' => 'screen' ),
- 'common/commonContent.css' => array( 'media' => 'screen' ),
- 'common/commonInterface.css' => array( 'media' => 'screen' ),
- 'monobook/main.css' => array( 'media' => 'screen' ),
- ),
- 'remoteBasePath' => $GLOBALS['wgStylePath'],
- 'localBasePath' => $GLOBALS['wgStyleDirectory'],
- ),
- // FIXME: Remove in favour of skins.vector.styles when cache expires
- 'skins.vector' => array(
- 'styles' => array(
- 'common/commonElements.css' => array( 'media' => 'screen' ),
- 'common/commonContent.css' => array( 'media' => 'screen' ),
- 'common/commonInterface.css' => array( 'media' => 'screen' ),
- 'vector/styles.less',
- ),
- 'remoteBasePath' => $GLOBALS['wgStylePath'],
- 'localBasePath' => $GLOBALS['wgStyleDirectory'],
- ),
'skins.vector.styles' => array(
// Used in the web installer. Test it after modifying this definition!
'styles' => array(
'styles' => 'resources/mediawiki.special/mediawiki.special.version.css',
),
- /* MediaWiki Tests */
-
- 'mediawiki.tests.qunit.testrunner' => array(
- 'scripts' => 'tests/qunit/data/testrunner.js',
- 'dependencies' => array(
- 'jquery.getAttrs',
- 'jquery.qunit',
- 'jquery.qunit.completenessTest',
- 'mediawiki.page.startup',
- 'mediawiki.page.ready',
- ),
- 'position' => 'top',
- 'targets' => array( 'desktop', 'mobile' ),
- ),
-
/* MediaWiki Legacy */
'mediawiki.legacy.ajax' => array(
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
+ if (this.options.className) {
+ $tip.addClass(maybeCall(this.options.className, this.$element[0]));
+ }
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
var pos = $.extend({}, this.$element.offset(), {
}
$tip.css(tp).addClass('tipsy-' + gravity);
- if (this.options.className) {
- $tip.addClass(maybeCall(this.options.className, this.$element[0]));
- }
if (this.options.fade) {
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}, 100);
if ( nav === undefined ) {
nav = window.navigator;
}
+
// Use the cached version if possible
- if ( profileCache[nav.userAgent] === undefined ) {
+ if ( profileCache[ nav.userAgent + '|' + nav.platform ] !== undefined ) {
+ return profileCache[ nav.userAgent + '|' + nav.platform ];
+ }
- var
- versionNumber,
+ var
+ versionNumber,
+ key = nav.userAgent + '|' + nav.platform,
- /* Configuration */
+ /* Configuration */
- // Name of browsers or layout engines we don't recognize
- uk = 'unknown',
- // Generic version digit
- x = 'x',
- // Strings found in user agent strings that need to be conformed
- wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3', 'Iceweasel'],
- // Translations for conforming user agent strings
- userAgentTranslations = [
- // Tons of browsers lie about being something they are not
- [/(Firefox|MSIE|KHTML,?\slike\sGecko|Konqueror)/, ''],
- // Chrome lives in the shadow of Safari still
- ['Chrome Safari', 'Chrome'],
- // KHTML is the layout engine not the browser - LIES!
- ['KHTML', 'Konqueror'],
- // Firefox nightly builds
- ['Minefield', 'Firefox'],
- // This helps keep different versions consistent
- ['Navigator', 'Netscape'],
- // This prevents version extraction issues, otherwise translation would happen later
- ['PLAYSTATION 3', 'PS3']
- ],
- // Strings which precede a version number in a user agent string - combined and used as
- // match 1 in version detection
- versionPrefixes = [
- 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
- 'lynx', 'msie', 'safari', 'ps3', 'android'
- ],
- // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
- versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
- // Names of known browsers
- names = [
- 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
- 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq', 'android'
- ],
- // Tanslations for conforming browser names
- nameTranslations = [],
- // Names of known layout engines
- layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'],
- // Translations for conforming layout names
- layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
- // Names of supported layout engines for version number
- layoutVersions = ['applewebkit', 'gecko', 'trident'],
- // Names of known operating systems
- platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
- // Translations for conforming operating system names
- platformTranslations = [ ['sunos', 'solaris'], ['wow64', 'win'] ],
+ // Name of browsers or layout engines we don't recognize
+ uk = 'unknown',
+ // Generic version digit
+ x = 'x',
+ // Strings found in user agent strings that need to be conformed
+ wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3', 'Iceweasel'],
+ // Translations for conforming user agent strings
+ userAgentTranslations = [
+ // Tons of browsers lie about being something they are not
+ [/(Firefox|MSIE|KHTML,?\slike\sGecko|Konqueror)/, ''],
+ // Chrome lives in the shadow of Safari still
+ ['Chrome Safari', 'Chrome'],
+ // KHTML is the layout engine not the browser - LIES!
+ ['KHTML', 'Konqueror'],
+ // Firefox nightly builds
+ ['Minefield', 'Firefox'],
+ // This helps keep different versions consistent
+ ['Navigator', 'Netscape'],
+ // This prevents version extraction issues, otherwise translation would happen later
+ ['PLAYSTATION 3', 'PS3']
+ ],
+ // Strings which precede a version number in a user agent string - combined and used as
+ // match 1 in version detection
+ versionPrefixes = [
+ 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
+ 'lynx', 'msie', 'safari', 'ps3', 'android'
+ ],
+ // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
+ versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
+ // Names of known browsers
+ names = [
+ 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
+ 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq', 'android'
+ ],
+ // Tanslations for conforming browser names
+ nameTranslations = [],
+ // Names of known layout engines
+ layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'],
+ // Translations for conforming layout names
+ layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
+ // Names of supported layout engines for version number
+ layoutVersions = ['applewebkit', 'gecko', 'trident'],
+ // Names of known operating systems
+ platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
+ // Translations for conforming operating system names
+ platformTranslations = [ ['sunos', 'solaris'], ['wow64', 'win'] ],
- /* Methods */
+ /* Methods */
- /**
- * Performs multiple replacements on a string
- */
- translate = function ( source, translations ) {
- var i;
- for ( i = 0; i < translations.length; i++ ) {
- source = source.replace( translations[i][0], translations[i][1] );
- }
- return source;
- },
+ /**
+ * Performs multiple replacements on a string
+ */
+ translate = function ( source, translations ) {
+ var i;
+ for ( i = 0; i < translations.length; i++ ) {
+ source = source.replace( translations[i][0], translations[i][1] );
+ }
+ return source;
+ },
- /* Pre-processing */
+ /* Pre-processing */
- ua = nav.userAgent,
- match,
- name = uk,
- layout = uk,
- layoutversion = uk,
- platform = uk,
- version = x;
+ ua = nav.userAgent,
+ match,
+ name = uk,
+ layout = uk,
+ layoutversion = uk,
+ platform = uk,
+ version = x;
- if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) {
- // Takes a userAgent string and translates given text into something we can more easily work with
- ua = translate( ua, userAgentTranslations );
- }
- // Everything will be in lowercase from now on
- ua = ua.toLowerCase();
+ if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) {
+ // Takes a userAgent string and translates given text into something we can more easily work with
+ ua = translate( ua, userAgentTranslations );
+ }
+ // Everything will be in lowercase from now on
+ ua = ua.toLowerCase();
- /* Extraction */
+ /* Extraction */
- if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) {
- name = translate( match[1], nameTranslations );
- }
- if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) {
- layout = translate( match[1], layoutTranslations );
- }
- if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) {
- layoutversion = parseInt( match[2], 10 );
- }
- if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) {
- platform = translate( match[1], platformTranslations );
- }
- if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) {
- version = match[3];
- }
+ if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) {
+ name = translate( match[1], nameTranslations );
+ }
+ if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) {
+ layout = translate( match[1], layoutTranslations );
+ }
+ if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) {
+ layoutversion = parseInt( match[2], 10 );
+ }
+ if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) {
+ platform = translate( match[1], platformTranslations );
+ }
+ if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) {
+ version = match[3];
+ }
- /* Edge Cases -- did I mention about how user agent string lie? */
+ /* Edge Cases -- did I mention about how user agent string lie? */
- // Decode Safari's crazy 400+ version numbers
- if ( name === 'safari' && version > 400 ) {
- version = '2.0';
- }
- // Expose Opera 10's lies about being Opera 9.8
- if ( name === 'opera' && version >= 9.8 ) {
- match = ua.match( /\bversion\/([0-9\.]*)/ );
- if ( match && match[1] ) {
- version = match[1];
- } else {
- version = '10';
- }
+ // Decode Safari's crazy 400+ version numbers
+ if ( name === 'safari' && version > 400 ) {
+ version = '2.0';
+ }
+ // Expose Opera 10's lies about being Opera 9.8
+ if ( name === 'opera' && version >= 9.8 ) {
+ match = ua.match( /\bversion\/([0-9\.]*)/ );
+ if ( match && match[1] ) {
+ version = match[1];
+ } else {
+ version = '10';
}
- // And Opera 15's lies about being Chrome
- if ( name === 'chrome' && ( match = ua.match( /\bopr\/([0-9\.]*)/ ) ) ) {
- if ( match[1] ) {
- name = 'opera';
- version = match[1];
- }
+ }
+ // And Opera 15's lies about being Chrome
+ if ( name === 'chrome' && ( match = ua.match( /\bopr\/([0-9\.]*)/ ) ) ) {
+ if ( match[1] ) {
+ name = 'opera';
+ version = match[1];
}
- // And IE 11's lies about being not being IE
- if ( layout === 'trident' && layoutversion >= 7 && ( match = ua.match( /\brv[ :\/]([0-9\.]*)/ ) ) ) {
- if ( match[1] ) {
- name = 'msie';
- version = match[1];
- }
+ }
+ // And IE 11's lies about being not being IE
+ if ( layout === 'trident' && layoutversion >= 7 && ( match = ua.match( /\brv[ :\/]([0-9\.]*)/ ) ) ) {
+ if ( match[1] ) {
+ name = 'msie';
+ version = match[1];
}
+ }
- versionNumber = parseFloat( version, 10 ) || 0.0;
+ versionNumber = parseFloat( version, 10 ) || 0.0;
- /* Caching */
+ /* Caching */
- profileCache[nav.userAgent] = {
- name: name,
- layout: layout,
- layoutVersion: layoutversion,
- platform: platform,
- version: version,
- versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ),
- versionNumber: versionNumber
- };
- }
- return profileCache[nav.userAgent];
+ return profileCache[ key ] = {
+ name: name,
+ layout: layout,
+ layoutVersion: layoutversion,
+ platform: platform,
+ version: version,
+ versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ),
+ versionNumber: versionNumber
+ };
},
/**
* Return false if fullscreen is not supported.
*/
setupFullscreen = function () {
- if ( document.fullscreenEnabled ||
- document.mozFullScreenEnabled ||
- document.webkitFullscreenEnabled ||
- document.msFullscreenEnabled
- ) {
+ if ( $.support.fullscreen ) {
// When the fullscreen mode is changed, trigger the
// fullscreen events (and when exiting,
// also remove the fullscreen class)
return this;
}
};
+
+ $.support.fullscreen = document.fullscreenEnabled ||
+ document.webkitFullscreenEnabled ||
+ document.mozFullScreenEnabled ||
+ document.msFullscreenEnabled;
}( jQuery ) );
/**
* Animate watch/unwatch links to use asynchronous API requests to
* watch pages, rather than navigating to a different URI.
+ *
+ * @class mw.page.watch.ajax
*/
( function ( mw, $ ) {
- /**
- * The name of the page to watch or unwatch.
- */
+ // The name of the page to watch or unwatch
var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) );
/**
* Update the link text, link href attribute and (if applicable)
* "loading" class.
*
- * @param $link {jQuery} Anchor tag of (un)watch link.
- * @param action {String} One of 'watch', 'unwatch'.
- * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'.
+ * @param {jQuery} $link Anchor tag of (un)watch link
+ * @param {string} action One of 'watch', 'unwatch'
+ * @param {string} [state="idle"] 'idle' or 'loading'. Default is 'idle'
*/
function updateWatchLink( $link, action, state ) {
var accesskeyTip, msgKey, $li, otherAction;
accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp );
$li = $link.closest( 'li' );
- /**
- * Trigger a 'watchpage' event for this List item.
- * Announce the otherAction value as the first param.
- * Used to monitor the state of watch link.
- * TODO: Revise when system wide hooks are implemented
- */
+ // Trigger a 'watchpage' event for this List item.
+ // Announce the otherAction value as the first param.
+ // Used to monitor the state of watch link.
+ // TODO: Revise when system wide hooks are implemented
if ( state === undefined ) {
$li.trigger( 'watchpage.mw', otherAction );
}
}
/**
- * @todo This should be moved somewhere more accessible.
- * @param url {String}
- * @return {String} The extracted action, defaults to 'view'.
+ * TODO: This should be moved somewhere more accessible.
+ *
+ * @private
+ * @param {string} url
+ * @return {string} The extracted action, defaults to 'view'
*/
function mwUriGetAction( url ) {
var action, actionPaths, key, i, m, parts;
actionPaths = mw.config.get( 'wgActionPaths' );
- // @todo Does MediaWiki give action path or query param
+ // TODO: Does MediaWiki give action path or query param
// precedence ? If the former, move this to the bottom
action = mw.util.getParamValue( 'action', url );
if ( action !== null ) {
return 'view';
}
- // Expose local methods
+ // Expose public methods
mw.page.watch = {
updateWatchLink: updateWatchLink
};
// Content styling
text-align: center;
font-weight: bold;
- white-space: nowrap;
text-shadow: 0 1px rgba(0, 0, 0, .1);
// Interaction styling
/**
* Utility functions for jazzing up HTMLForm elements.
+ *
+ * @class jQuery.plugin.htmlform
*/
( function ( mw, $ ) {
/**
* jQuery plugin to fade or snap to visible state.
*
- * @param {boolean} instantToggle [optional]
+ * @param {boolean} [instantToggle=false]
* @return {jQuery}
*/
$.fn.goIn = function ( instantToggle ) {
/**
* jQuery plugin to fade or snap to hiding state.
*
- * @param {boolean} instantToggle [optional]
+ * @param {boolean} [instantToggle=false]
* @return jQuery
*/
$.fn.goOut = function ( instantToggle ) {
/**
* Bind a function to the jQuery object via live(), and also immediately trigger
* the function on the objects with an 'instant' parameter set to true.
- * @param {Function} callback Takes one parameter, which is {true} when the
- * event is called immediately, and {jQuery.Event} when triggered from an event.
+ * @param {Function} callback
+ * @param {boolean|jQuery.Event} callback.immediate True when the event is called immediately,
+ * an event object when triggered from an event.
*/
$.fn.liveAndTestAtStart = function ( callback ) {
$( this )
} );
}
} );
+
+ /**
+ * @class jQuery
+ * @mixins jQuery.plugin.htmlform
+ */
}( mediaWiki, jQuery ) );
// make sure paste and cut events from the mouse and drag&drop events
// trigger the keypress handler and cause the suggestions to update
$( this ).trigger( 'keypress' );
- } )
- // If the forms include any fulltext search thingies, remove them as they
- // would interfere with selecting suggestions
- .closest( 'form' ).find( '[name="fulltext"]' ).remove();
+ } );
// Ensure that the thing is actually present!
if ( $searchRegion.length === 0 ) {
$region: $searchRegion
} );
+ // If the form includes any fallback fulltext search buttons, remove them
+ $searchInput.closest( 'form' ).find( '.mw-fallbackSearchButton' ).remove();
+
// In most skins (at least Monobook and Vector), the font-size is messed up in <body>.
// (they use 2 elements to get a sane font-height). So, instead of making exceptions for
// each skin or adding more stylesheets, just copy it from the active element so auto-fit.
/**
* Add the appropriate prefix to the accesskey shown in the tooltip.
- * If the nodeList parameter is given, only those nodes are updated;
- * otherwise, all the nodes that will probably have accesskeys by
- * default are updated.
+ *
+ * If the `$nodes` parameter is given, only those nodes are updated;
+ * otherwise, depending on browser support, we update either all elements
+ * with accesskeys on the page or a bunch of elements which are likely to
+ * have them on core skins.
*
* @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
*/
updateTooltipAccessKeys: function ( $nodes ) {
if ( !$nodes ) {
- // Rather than going into a loop of all anchor tags, limit to few elements that
- // contain the relevant anchor tags.
- // Input and label are rare enough that no such optimization is needed
- $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label' );
+ if ( document.querySelectorAll ) {
+ // If we're running on a browser where we can do this efficiently,
+ // just find all elements that have accesskeys. We can't use jQuery's
+ // polyfill for the selector since looping over all elements on page
+ // load might be too slow.
+ $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+ } else {
+ // Otherwise go through some elements likely to have accesskeys rather
+ // than looping over all of them. Unfortunately this will not fully
+ // work for custom skins with different HTML structures. Input, label
+ // and button should be rare enough that no optimizations are needed.
+ $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+ }
} else if ( !( $nodes instanceof $ ) ) {
$nodes = $( $nodes );
}
// * The mediawiki.searchSuggest module, after doing tests for the broken browsers, removes
// the 'fulltext' button and handles 'fulltext' search itself; this will reveal the 'go'
// button and cause it to be used.
- echo $this->makeSearchButton( 'fulltext', array( 'id' => 'mw-searchButton', 'class' => 'searchButton' ) );
+ echo $this->makeSearchButton( 'fulltext', array( 'id' => 'mw-searchButton', 'class' => 'searchButton mw-fallbackSearchButton' ) );
echo $this->makeSearchButton( 'go', array( 'id' => 'searchButton', 'class' => 'searchButton' ) );
?>
</div>
.background-image('images/search-fade.png');
background-position: top left;
background-repeat: repeat-x;
-}
-
-// Styles for both the search input and the button
-div#simpleSearch input {
- position: absolute;
- margin: 0;
- padding: 0;
- border: 0;
- color: black;
- background-color: transparent;
-}
-
-// The search input
-div#simpleSearch #searchInput {
- top: 0;
- left: 0;
- width: 90%;
- padding: 0.2em 0 0.2em 0.2em;
- font-size: 13px;
- direction: ltr;
-}
-div#simpleSearch #searchInput:focus {
- outline: none;
-}
-
-div#simpleSearch input {
- color: black;
-}
-
-// Placeholder colors. These rules MAY NOT be merged because of how
-// CSS requires browsers to parse unrecognized selectors!
-div#simpleSearch #searchInput.placeholder {
- color: #999;
-}
-div#simpleSearch #searchInput::-webkit-input-placeholder {
- color: #999;
-}
-div#simpleSearch #searchInput:-moz-placeholder {
- color: #999;
-}
-div#simpleSearch #searchInput:-ms-input-placeholder {
- color: #999;
-}
+ // Styles for both the search input and the button
+ input {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background-color: transparent;
+ color: black;
+ }
-// Undo the styles Webkit browsers apply to type=search fields,
-// we provide our own
-div#simpleSearch #searchInput {
- -webkit-appearance: textfield;
-}
-div#simpleSearch #searchInput::-webkit-search-decoration,
-div#simpleSearch #searchInput::-webkit-search-cancel-button,
-div#simpleSearch #searchInput::-webkit-search-results-button,
-div#simpleSearch #searchInput::-webkit-search-results-decoration {
- -webkit-appearance: textfield;
-}
+ // The search input
+ #searchInput {
+ top: 0;
+ left: 0;
+ width: 90%;
+ padding: 0.2em 0 0.2em 0.2em;
+ font-size: 13px;
+ direction: ltr;
+
+ &:focus {
+ outline: none;
+ }
+
+ // These rules MAY NOT be merged because of how CSS requires browsers
+ // to parse unrecognized selectors!
+ &.placeholder {
+ color: #999;
+ }
+ &:-ms-input-placeholder {
+ color: #999;
+ }
+ &:-moz-placeholder {
+ color: #999;
+ }
+ &::-webkit-input-placeholder {
+ color: #999;
+ }
+
+ // Undo the styles Webkit browsers apply to type=search fields,
+ // we provide our own
+ -webkit-appearance: textfield;
+
+ &::-webkit-search-decoration,
+ &::-webkit-search-cancel-button,
+ &::-webkit-search-results-button,
+ &::-webkit-search-results-decoration {
+ -webkit-appearance: textfield;
+ }
+ }
-// The buttons. They are displayed in the same position, and if both are
-// present the fulltext search one obscures the 'Go' one.
-div#simpleSearch #searchButton,
-div#simpleSearch #mw-searchButton {
- top: 0;
- right: 0;
- width: 10%;
- height: 100%;
- cursor: pointer;
- /* Hide button text and replace it with the image. */
- text-indent: 100%;
- /* Needed to make IE6 respect the text-indent. */
- line-height: 1;
- /* Opera 12 on RTL flips the text in a funny way without this. */
- /* @noflip */
- direction: ltr;
- white-space: nowrap;
- overflow: hidden;
- /* @embed */
- background: transparent url(images/search-ltr.png) center center no-repeat;
-}
+ // The buttons. They are displayed in the same position, and if both are
+ // present the fulltext search one obscures the 'Go' one.
+ #searchButton,
+ #mw-searchButton {
+ top: 0;
+ right: 0;
+ width: 10%;
+ height: 100%;
+ cursor: pointer;
+ /* Hide button text and replace it with the image. */
+ /* This would be 100% if not for Firefox shenanigans (bug 60900). */
+ text-indent: 200%;
+ /* Needed to make IE6 respect the text-indent. */
+ line-height: 1;
+ /* Opera 12 on RTL flips the text in a funny way without this. */
+ /* @noflip */
+ direction: ltr;
+ white-space: nowrap;
+ overflow: hidden;
+ .background-image-svg('images/search-ltr.svg', 'images/search-ltr.png');
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
-div#simpleSearch #mw-searchButton {
- z-index: 1;
+ #mw-searchButton {
+ z-index: 1;
+ }
}
-
// The following styles exist only for backwards-compatibility with
// cached HTML and are to be removed before 1.23 release.
padding-right: 0.4em;
margin: 0;
border: none;
+ background-color: transparent;
background-image: none;
text-indent: 0;
-}
-/* OVERRIDDEN BY COMPLIANT BROWSERS */
-div#simpleSearch button#searchButton img {
- border: none;
- margin: 0;
- margin-top: -3px;
- padding: 0;
-}
-
-/* IGNORED BY IE6 */
-div#simpleSearch button#searchButton > img {
- margin: 0;
+ /* OVERRIDDEN BY COMPLIANT BROWSERS */
+ img {
+ border: none;
+ margin: 0;
+ margin-top: -3px;
+ padding: 0;
+ }
+ /* IGNORED BY IE6 */
+ > img {
+ margin: 0;
+ }
}
-
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13">
+ <g stroke-width="2" stroke="#6c6c6c" fill="none">
+ <path d="m11.29 11.71-4-4"/>
+ <circle cx="5" cy="5" r="4"/>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13">
+ <g stroke-width="2" stroke="#6c6c6c" fill="none">
+ <path d="m.71 11.71 4-4"/>
+ <circle cx="7" cy="5" r="4"/>
+ </g>
+</svg>
div#content {
margin-left: 11em;
- padding: 1.5em 1.5em 1.5em 1.75em;
+ padding: 1.25em 1.5em 1.5em 1.5em;
}
#p-logo {
left: @menu-main-logo-left;
@content-font-color: black;
@content-font-size: 0.8em;
@content-line-height: 1.5em;
-@content-padding: 1.25em 1.5em 1.5em 1.5em;
+@content-padding: 1em;
@content-heading-font-size: 1.6em;
@content-heading-font-family: sans-serif;
@body-background-color: #fff;
* @todo This method should be split into 2 separate tests each with a provider
*/
public function testSecureAndSplit() {
+ $this->setMwGlobals( array(
+ 'wgLocalInterwiki' => 'localtestiw',
+ 'wgHooks' => array(
+ 'InterwikiLoadPrefix' => array(
+ function ( $prefix, &$data ) {
+ if ( $prefix === 'localtestiw' ) {
+ $data = array( 'iw_url' => 'localtestiw' );
+ } elseif ( $prefix === 'remotetestiw' ) {
+ $data = array( 'iw_url' => 'remotetestiw' );
+ }
+ return false;
+ }
+ )
+ )
+ ));
// Valid
foreach ( array(
'Sandbox',
'A~~',
// Length is 256 total, but only title part matters
'Category:' . str_repeat( 'x', 248 ),
- str_repeat( 'x', 252 )
+ str_repeat( 'x', 252 ),
+ // interwiki prefix
+ 'localtestiw: #anchor',
+ 'localtestiw:foo',
+ 'localtestiw: foo # anchor',
+ 'localtestiw: Talk: Sandbox # anchor',
+ 'remotetestiw:',
+ 'remotetestiw: Talk: # anchor',
+ 'remotetestiw: #bar',
+ 'remotetestiw: Talk:',
+ 'remotetestiw: Talk: Foo'
) as $text ) {
$this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" );
}
// Namespace prefix without actual title
'Talk:',
'Category: ',
- 'Category: #bar'
+ 'Category: #bar',
+ // interwiki prefix
+ 'localtestiw:',
+ 'localtestiw: Talk: # anchor',
+ 'localtestiw: Talk:'
) as $text ) {
$this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
}
'testmultiselect-opt2' => 'registered-multiselect',
'testmultiselect-opt3' => 'registered-multiselect',
'testmultiselect-opt4' => 'registered-multiselect',
+ 'special' => 'special',
);
if ( $options === null ) {
$this->assertEquals( self::$Success, $response );
}
+ public function testSpecialOption() {
+ $this->mUserMock->expects( $this->never() )
+ ->method( 'resetOptions' );
+
+ $this->mUserMock->expects( $this->never() )
+ ->method( 'saveSettings' );
+
+ $request = $this->getSampleRequest( array(
+ 'change' => 'special=1'
+ ) );
+
+ $response = $this->executeQuery( $request );
+
+ $this->assertEquals( array(
+ 'options' => 'success',
+ 'warnings' => array(
+ 'options' => array(
+ '*' => "Validation error for 'special': cannot be set by this module"
+ )
+ )
+ ), $response );
+ }
+
public function testUnknownOption() {
$this->mUserMock->expects( $this->never() )
->method( 'resetOptions' );
<?php
+/* Modules registered when $wgEnableJavaScriptTest is true */
+
return array(
- /* Test suites for MediaWiki core modules */
+ /* Utilities */
+
+ 'test.mediawiki.qunit.testrunner' => array(
+ 'scripts' => array(
+ 'tests/qunit/data/testrunner.js',
+ ),
+ 'dependencies' => array(
+ 'jquery.getAttrs',
+ 'jquery.qunit',
+ 'jquery.qunit.completenessTest',
+ 'mediawiki.page.ready',
+ 'mediawiki.page.startup',
+ ),
+ 'position' => 'top',
+ 'targets' => array( 'desktop', 'mobile' ),
+ ),
+
+ /*
+ Test suites for MediaWiki core modules
+ These must have a dependency on test.mediawiki.qunit.testrunner!
+ */
- 'mediawiki.tests.qunit.suites' => array(
+ 'test.mediawiki.qunit.suites' => array(
'scripts' => array(
'tests/qunit/suites/resources/startup.test.js',
'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js',
'mediawiki.special.recentchanges',
'mediawiki.language',
'mediawiki.cldr',
+ 'test.mediawiki.qunit.testrunner',
),
)
);
mw.config.values = freshConfigCopy( localEnv.config );
mw.messages.values = freshMessagesCopy( localEnv.messages );
- localEnv.setup();
+ localEnv.setup.call( this );
},
teardown: function () {
log( 'MwEnvironment> TEARDOWN for "' + QUnit.config.current.module
+ ': ' + QUnit.config.current.testName + '"' );
- localEnv.teardown();
+ localEnv.teardown.call( this );
// Farewell, mock environment!
mw.config.values = liveConfig;
* initializations defined above in this file.
*/
envExecCount = 0;
- QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment( {
+ QUnit.module( 'test.mediawiki.qunit.testrunner', QUnit.newMwEnvironment( {
setup: function () {
envExecCount += 1;
this.mwHtmlLive = mw.html;
} );
- QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
+ QUnit.module( 'test.mediawiki.qunit.testrunner-after', QUnit.newMwEnvironment() );
QUnit.test( 'Teardown', 3, function ( assert ) {
assert.equal( mw.html.escape( '<' ), '<', 'extra teardown() callback was ran.' );