# legacy scripts
skins/common/IEFixes.js
skins/common/config.js
-skins/common/protect.js
-skins/common/upload.js
# github.com/jshint/jshint/issues/729
tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
$wgRCFeeds configuration array. $wgRCFeeds makes both the format and
destination of recent change notifications customizable, and allows for
multiple destinations to be specified.
+* (bug 53862) portal-url, currentevents-url and helppage have been removed from the
+ default Sidebar.
=== New features in 1.22 ===
* (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes.
* IPv6 addresses in X-Forwarded-For headers are now normalised before checking
against allowed proxy lists.
* Add deferrable update support for callback/closure
+* Add TitleMove hook before page renames
+* Revision deletion backend code is moved out of SpecialRevisiondelete
+* Add a variable (wgRedactedFunctionArguments) to redact the values sent as certain function
+ parameters from exception stack traces.
+* Added {{REVISIONSIZE}} variable to get the current size of a revision.
=== Bug fixes in 1.22 ===
* Disable Special:PasswordReset when $wgEnableEmail is false. Previously one
* mw.util.tooltipAccessKeyRegexp: The regex now matches "option-" as well.
Support for Mac "option" was added in 1.16, but the regex was never updated.
* (bug 46768) Usernames of blocking users now display correctly, even if numeric.
-* (bug 39590) {{PAGESIZE}} for the current page and self-transclusions now
- show the most up to date result always instead of being a revision behind.
+* (bug 39590) Self-transclusions now show the most up to date result always
+ after save instead of being a revision behind.
* A bias in wfRandomString() toward digits 1-7 has been corrected. Generated
strings will now start with digits 0 and 8-f as often as they should.
* (bug 45371) Removed Parser_LinkHooks and CoreLinkFunctions classes.
Hooks may change this value to override the return value of
Title::isWikitextPage()
+'TitleMove': Before moving an article (title).
+$old: old title
+$nt: new title
+$user: user who does the move
+
'TitleMoveComplete': After moving an article (title).
$old: old title
$nt: new title
return 'view';
}
- $action = Action::factory( $actionName, $context->getWikiPage() );
+ $action = Action::factory( $actionName, $context->getWikiPage(), $context );
if ( $action instanceof Action ) {
return $action->getName();
}
final public function getContext() {
if ( $this->context instanceof IContextSource ) {
return $this->context;
+ } else if ( $this->page instanceof Article ) {
+ // NOTE: $this->page can be a WikiPage, which does not have a context.
+ wfDebug( __METHOD__ . ': no context known, falling back to Article\'s context.' );
+ return $this->page->getContext();
}
- return $this->page->getContext();
+
+ wfWarn( __METHOD__ . ': no context known, falling back to RequestContext::getMain().' );
+ return RequestContext::getMain();
}
/**
* @param $context IContextSource
*/
public function __construct( Page $page, IContextSource $context = null ) {
+ if ( $context === null ) {
+ wfWarn( __METHOD__ . ' called without providing a Context object.' );
+ // NOTE: We could try to initialize $context using $page->getContext(),
+ // if $page is an Article. That however seems to not work seamlessly.
+ }
+
$this->page = $page;
$this->context = $context;
}
public function execute( array $data = null, $captureErrors = true ) {
try {
// Set a new context so output doesn't leak.
- $this->context = clone $this->page->getContext();
+ $this->context = clone $this->getContext();
// This will throw exceptions if there's a problem
$this->checkCanExecute( $this->getUser() );
public function execute( array $data = null, $captureErrors = true ) {
try {
// Set a new context so output doesn't leak.
- $this->context = clone $this->page->getContext();
+ $this->context = clone $this->getContext();
if ( is_array( $data ) ) {
$this->context->setRequest( new FauxRequest( $data, false ) );
}
$wgMemc->set( $key, $emptyTags, 300 );
return $emptyTags;
}
+
+ /**
+ * Returns a map of any tags used on the wiki to number of edits
+ * tagged with them, ordered descending by the hitcount.
+ *
+ * @return array Array of string => int
+ */
+ public static function tagUsageStatistics() {
+ $out = array();
+
+ $dbr = wfGetDB( DB_SLAVE );
+ $res = $dbr->select(
+ 'change_tag',
+ array( 'ct_tag', 'hitcount' => 'count(*)' ),
+ array(),
+ __METHOD__,
+ array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' )
+ );
+
+ foreach ( $res as $row ) {
+ $out[$row->ct_tag] = $row->hitcount;
+ }
+ foreach ( self::listDefinedTags() as $tag ) {
+ if ( !isset( $out[$tag] ) ) {
+ $out[$tag] = 0;
+ }
+ }
+
+ return $out;
+ }
}
*/
$wgShowExceptionDetails = false;
+/**
+ * Array of functions which need parameters redacted from stack traces shown to
+ * clients and logged. Keys are in the format '[class::]function', and the
+ * values should be either an integer or an array of integers. These are the
+ * indexes of the parameters which need to be kept secret.
+ * @since 1.22
+ */
+$wgRedactedFunctionArguments = array(
+ 'AuthPlugin::setPassword' => 1,
+ 'AuthPlugin::authenticate' => 1,
+ 'AuthPlugin::addUser' => 1,
+
+ 'DatabaseBase::__construct' => 2,
+ 'DatabaseBase::open' => 2,
+
+ 'SpecialChangeEmail::attemptChange' => 1,
+ 'SpecialChangePassword::attemptReset' => 0,
+
+ 'User::setPassword' => 0,
+ 'User::setInternalPassword' => 0,
+ 'User::checkPassword' => 0,
+ 'User::setNewpassword' => 0,
+ 'User::comparePasswords' => array( 0, 1 ),
+ 'User::checkTemporaryPassword' => 0,
+ 'User::setToken' => 0,
+ 'User::crypt' => 0,
+ 'User::oldCrypt' => 0,
+ 'User::getPasswordValidity' => 0,
+ 'User::isValidPassword' => 0,
+);
+
/**
* If true, show a backtrace for database errors
*/
if ( $wgShowExceptionDetails ) {
return '<p>' . nl2br( htmlspecialchars( $this->getMessage() ) ) .
- '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
+ '</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( MWExceptionHandler::formatRedactedTrace( $this ) ) ) .
"</p>\n";
} else {
return "<div class=\"errorbox\">" .
if ( $wgShowExceptionDetails ) {
return $this->getMessage() .
- "\nBacktrace:\n" . $this->getTraceAsString() . "\n";
+ "\nBacktrace:\n" . MWExceptionHandler::formatRedactedTrace( $this ) . "\n";
} else {
return "Set \$wgShowExceptionDetails = true; " .
"in LocalSettings.php to show detailed debugging information.\n";
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
- global $wgLogExceptionBacktrace, $wgMimeType;
- $log = $this->getLogMessage();
+ global $wgMimeType;
- if ( $log ) {
- if ( $wgLogExceptionBacktrace ) {
- wfDebugLog( 'exception', $log . "\n" . $this->getTraceAsString() . "\n" );
- } else {
- wfDebugLog( 'exception', $log );
- }
- }
+ $this->logException();
if ( defined( 'MW_API' ) ) {
// Unhandled API exception, we can't be sure that format printer is alive
}
}
+ /**
+ * Log the error message to the exception log (if enabled)
+ */
+ function logException() {
+ global $wgLogExceptionBacktrace;
+
+ $log = $this->getLogMessage();
+ if ( $log ) {
+ if ( $wgLogExceptionBacktrace ) {
+ wfDebugLog( 'exception', $log . "\n" . MWExceptionHandler::formatRedactedTrace( $this ) . "\n" );
+ } else {
+ wfDebugLog( 'exception', $log );
+ }
+ }
+ }
+
/**
* Check whether we are in command line mode or not to report the exception
* in the correct format.
$message = "MediaWiki internal error.\n\n";
if ( $wgShowExceptionDetails ) {
- $message .= 'Original exception: ' . $e->__toString() . "\n\n" .
+ $message .= 'Original exception: ' . self::formatRedactedTrace( $e ) . "\n\n" .
'Exception caught inside exception handler: ' . $e2->__toString();
} else {
$message .= "Exception caught inside exception handler.\n\n" .
}
}
} else {
- $message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"\n" .
- $e->__toString() . "\n";
+ $message = "Unexpected non-MediaWiki exception encountered, of type \"" . get_class( $e ) . "\"";
if ( $wgShowExceptionDetails ) {
- $message .= "\n" . $e->getTraceAsString() . "\n";
+ $message .= "\nexception '" . get_class( $e ) . "' in " . $e->getFile() . ":" . $e->getLine() . "\nStack trace:\n" . self::formatRedactedTrace( $e ) . "\n";
}
if ( $cmdLine ) {
// Exit value should be nonzero for the benefit of shell jobs
exit( 1 );
}
+
+ /**
+ * Get the stack trace from the exception as a string, redacting certain function arguments in the process
+ * @param Exception $e The exception
+ * @return string The stack trace as a string
+ */
+ public static function formatRedactedTrace( Exception $e ) {
+ global $wgRedactedFunctionArguments;
+ $finalExceptionText = '';
+
+ foreach ( $e->getTrace() as $i => $call ) {
+ $checkFor = array();
+ if ( isset( $call['class'] ) ) {
+ $checkFor[] = $call['class'] . '::' . $call['function'];
+ foreach ( class_parents( $call['class'] ) as $parent ) {
+ $checkFor[] = $parent . '::' . $call['function'];
+ }
+ } else {
+ $checkFor[] = $call['function'];
+ }
+
+ foreach ( $checkFor as $check ) {
+ if ( isset( $wgRedactedFunctionArguments[$check] ) ) {
+ foreach ( (array)$wgRedactedFunctionArguments[$check] as $argNo ) {
+ $call['args'][$argNo] = 'REDACTED';
+ }
+ }
+ }
+
+ $finalExceptionText .= "#{$i} {$call['file']}({$call['line']}): ";
+ if ( isset( $call['class'] ) ) {
+ $finalExceptionText .= $call['class'] . $call['type'] . $call['function'];
+ } else {
+ $finalExceptionText .= $call['function'];
+ }
+ $args = array();
+ foreach ( $call['args'] as $arg ) {
+ if ( is_object( $arg ) ) {
+ $args[] = 'Object(' . get_class( $arg ) . ')';
+ } elseif( is_array( $arg ) ) {
+ $args[] = 'Array';
+ } else {
+ $args[] = var_export( $arg, true );
+ }
+ }
+ $finalExceptionText .= '(' . implode( ', ', $args ) . ")\n";
+ }
+ return $finalExceptionText . '#' . ( $i + 1 ) . ' {main}';
+ }
}
/**
* Get an URL to a web viewer link to the HEAD revision.
*
- * @return string|bool string if an URL is available or false otherwise.
+ * @return string|bool string if a URL is available or false otherwise.
*/
public function getHeadViewUrl() {
$config = "{$this->basedir}/config";
return Fallback::mb_strrpos( $haystack, $needle, $offset, $encoding );
}
}
+
+// gzdecode function only exists in PHP >= 5.4.0
+// http://php.net/gzdecode
+if ( !function_exists( 'gzdecode' ) ) {
+ /**
+ * @codeCoverageIgnore
+ * @return string
+ */
+ function gzdecode( $data ) {
+ return gzinflate( substr( $data, 10, -8 ) );
+ }
+}
/// @endcond
/**
'revisionyear',
'revisiontimestamp',
'revisionuser',
+ 'revisionsize',
'subpagename',
'subpagenamee',
'talkspace',
* List of all named character entities defined in HTML 4.01
* http://www.w3.org/TR/html4/sgml/entities.html
* As well as ' which is only defined starting in XHTML1.
- * @private
*/
private static $htmlEntities = array(
'Aacute' => 193,
/**
* Lazy-initialised attributes regex, see getAttribsRegex()
- * @private
*/
private static $attribsRegex;
* unit testing our internal implementation.
*
* @since 1.21
+ * @note In MediaWiki 1.21, this function did not provide proper UTF-8 validation.
+ * In particular, the pure PHP code path did not in fact check for overlong forms.
+ * Beware of this when backporting code to that version of MediaWiki.
*
* @param string $value String to check
* @param boolean $disableMbstring Whether to use the pure PHP
* @return boolean Whether the given $value is a valid UTF-8 encoded string
*/
static function isUtf8( $value, $disableMbstring = false ) {
+ $value = (string)$value;
- if ( preg_match( '/[\x80-\xff]/', $value ) === 0 ) {
- # no high bit set, this is pure ASCII which is de facto
- # valid UTF-8
+ // If the mbstring extension is loaded, use it. However, before PHP 5.4, values above
+ // U+10FFFF are incorrectly allowed, so we have to check for them separately.
+ if ( !$disableMbstring && function_exists( 'mb_check_encoding' ) ) {
+ static $newPHP;
+ if ( $newPHP === null ) {
+ $newPHP = !mb_check_encoding( "\xf4\x90\x80\x80", 'UTF-8' );
+ }
+
+ return mb_check_encoding( $value, 'UTF-8' ) &&
+ ( $newPHP || preg_match( "/\xf4[\x90-\xbf]|[\xf5-\xff]/S", $value ) === 0 );
+ }
+
+ if ( preg_match( "/[\x80-\xff]/S", $value ) === 0 ) {
+ // String contains only ASCII characters, has to be valid
return true;
}
- if ( !$disableMbstring && function_exists( 'mb_check_encoding' ) ) {
- return mb_check_encoding( $value, 'UTF-8' );
- } else {
- $hasUtf8 = preg_match( '/^(?>
- [\x00-\x7f]
- | [\xc0-\xdf][\x80-\xbf]
- | [\xe0-\xef][\x80-\xbf]{2}
- | [\xf0-\xf7][\x80-\xbf]{3}
- | [\xf8-\xfb][\x80-\xbf]{4}
- | \xfc[\x84-\xbf][\x80-\xbf]{4}
- )+$/x', $value );
- return ( $hasUtf8 > 0 );
+ // PCRE implements repetition using recursion; to avoid a stack overflow (and segfault)
+ // for large input, we check for invalid sequences (<= 5 bytes) rather than valid
+ // sequences, which can be as long as the input string is. Multiple short regexes are
+ // used rather than a single long regex for performance.
+ static $regexes;
+ if ( $regexes === null ) {
+ $cont = "[\x80-\xbf]";
+ $after = "(?!$cont)"; // "(?:[^\x80-\xbf]|$)" would work here
+ $regexes = array(
+ // Continuation byte at the start
+ "/^$cont/",
+
+ // ASCII byte followed by a continuation byte
+ "/[\\x00-\x7f]$cont/S",
+
+ // Illegal byte
+ "/[\xc0\xc1\xf5-\xff]/S",
+
+ // Invalid 2-byte sequence, or valid one then an extra continuation byte
+ "/[\xc2-\xdf](?!$cont$after)/S",
+
+ // Invalid 3-byte sequence, or valid one then an extra continuation byte
+ "/\xe0(?![\xa0-\xbf]$cont$after)/",
+ "/[\xe1-\xec\xee\xef](?!$cont{2}$after)/S",
+ "/\xed(?![\x80-\x9f]$cont$after)/",
+
+ // Invalid 4-byte sequence, or valid one then an extra continuation byte
+ "/\xf0(?![\x90-\xbf]$cont{2}$after)/",
+ "/[\xf1-\xf3](?!$cont{3}$after)/S",
+ "/\xf4(?![\x80-\x8f]$cont{2}$after)/",
+ );
}
+
+ foreach ( $regexes as $regex ) {
+ if ( preg_match( $regex, $value ) !== 0 ) {
+ return false;
+ }
+ }
+ return true;
}
/**
/**
* More or less "markup-safe" explode()
* Ignores any instances of the separator inside <...>
- * @param $separator String
- * @param $text String
+ * @param string $separator
+ * @param string $text
* @return array
*/
static function explodeMarkup( $separator, $text ) {
* Escape a string to make it suitable for inclusion in a preg_replace()
* replacement parameter.
*
- * @param $string String
- * @return String
+ * @param string $string
+ * @return string
*/
static function escapeRegexReplacement( $string ) {
$string = str_replace( '\\', '\\\\', $string );
/**
* Workalike for explode() with limited memory usage.
* Returns an Iterator
- * @param $separator
- * @param $subject
+ * @param string $separator
+ * @param string $subject
* @return ArrayIterator|ExplodeIterator
*/
static function explode( $separator, $subject ) {
var $r;
/**
- * @param $r string
+ * @param string $r
*/
function __construct( $r ) {
$this->r = $r;
}
/**
- * @param $matches array
+ * @param array $matches
* @return string
*/
function replace( $matches ) {
/**
* @param $from
* @param $to
- * @param $index int
+ * @param int $index
*/
function __construct( $from, $to, $index = 0 ) {
$this->from = $from;
}
/**
- * @param $matches array
+ * @param array $matches
* @return mixed
*/
function replace( $matches ) {
/**
* @param $table
- * @param $index int
+ * @param int $index
*/
function __construct( $table, $index = 0 ) {
$this->table = $table;
}
/**
- * @param $matches array
+ * @param array $matches
* @return mixed
*/
function replace( $matches ) {
/**
* Set the whole replacement array at once
+ * @param array $data
*/
function setArray( $data ) {
$this->data = $data;
/**
* Set an element of the replacement array
- * @param $from string
- * @param $to string
+ * @param string $from
+ * @param string $to
*/
function setPair( $from, $to ) {
$this->data[$from] = $to;
}
/**
- * @param $data array
+ * @param array $data
*/
function mergeArray( $data ) {
$this->data = array_merge( $this->data, $data );
}
/**
- * @param $other
+ * @param ReplacementArray $other
*/
function merge( $other ) {
$this->data = array_merge( $this->data, $other->data );
}
/**
- * @param $from string
+ * @param string $from
*/
function removePair( $from ) {
unset( $this->data[$from] );
}
/**
- * @param $data array
+ * @param array $data
*/
function removeArray( $data ) {
foreach ( $data as $from => $to ) {
}
/**
- * @param $subject string
+ * @param string $subject
* @return string
*/
function replace( $subject ) {
/**
* Construct a DelimIterator
- * @param $delim string
- * @param $s string
+ * @param string $delim
+ * @param string $subject
*/
- function __construct( $delim, $s ) {
- $this->subject = $s;
+ function __construct( $delim, $subject ) {
+ $this->subject = $subject;
$this->delim = $delim;
// Micro-optimisation (theoretical)
- $this->subjectLength = strlen( $s );
+ $this->subjectLength = strlen( $subject );
$this->delimLength = strlen( $delim );
$this->rewind();
return $this->current;
}
+ /**
+ * @return int|bool Current position or boolean false if invalid
+ */
function key() {
return $this->curPos;
}
$createRedirect = true;
}
+ wfRunHooks( 'TitleMove', array( $this, $nt, $wgUser ) );
+
// If it is a file, move it first.
// It is done before all other moving stuff is done because it's hard to revert.
$dbw = wfGetDB( DB_MASTER );
return;
}
- if ( function_exists( 'apache_request_headers' ) ) {
- foreach ( apache_request_headers() as $tempName => $tempValue ) {
+ $apacheHeaders = function_exists( 'apache_request_headers' ) ? apache_request_headers() : false;
+ if ( $apacheHeaders ) {
+ foreach ( $apacheHeaders as $tempName => $tempValue ) {
$this->headers[strtoupper( $tempName )] = $tempValue;
}
} else {
$act = $this->getAction();
- $action = Action::factory( $act, $page );
+ $action = Action::factory( $act, $page, $this->context );
+
if ( $action instanceof Action ) {
# Let Squid cache things if we can purge them.
if ( $wgUseSquid &&
protected function feedItem( $row ) {
$title = Title::makeTitle( intval( $row->page_namespace ), $row->page_title );
- if ( $title && $title->userCan( 'read' ) ) {
+ if ( $title && $title->userCan( 'read', $this->getUser() ) ) {
$date = $row->rev_timestamp;
$comments = $title->getTalkPage()->getFullURL();
$revision = Revision::newFromRow( $row );
<?php
/**
- * PhpRedis client connection pooling manager.
+ * Redis client connection pooling manager.
*
* 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
*/
/**
- * Helper class to manage redis connections using PhpRedis.
+ * Helper class to manage Redis connections.
*
* This can be used to get handle wrappers that free the handle when the wrapper
* leaves scope. The maximum number of free handles (connections) is configurable.
* @param array $options
*/
protected function __construct( array $options ) {
- if ( !extension_loaded( 'redis' ) ) {
- throw new MWException( __CLASS__ . ' requires the phpredis extension: ' .
- 'https://github.com/nicolasff/phpredis' );
+ if ( !class_exists( 'Redis' ) ) {
+ throw new MWException( __CLASS__ . ' requires a Redis client library. ' .
+ 'See https://www.mediawiki.org/wiki/Redis#Setup' );
}
$this->connectTimeout = $options['connectTimeout'];
$this->persistent = $options['persistent'];
break;
}
- return parent::tableName( strtoupper( $name ), $format );
+ return strtoupper( parent::tableName( $name, $format ) );
}
function tableNameInternal( $name ) {
/**
* Query whether a given table exists (in the given schema, or the default mw one if not given)
- * @return int
+ * @return bool
*/
function tableExists( $table, $fname = __METHOD__ ) {
$table = $this->tableName( $table );
$owner = $this->addQuotes( strtoupper( $this->mDBname ) );
$SQL = "SELECT 1 FROM all_tables WHERE owner=$owner AND table_name=$table";
$res = $this->doQuery( $SQL );
- if ( $res ) {
- $count = $res->numRows();
- $res->free();
+ if ( $res && $res->numRows() > 0 ) {
+ $exists = true;
} else {
- $count = 0;
+ $exists = false;
}
- return $count;
+
+ $res->free();
+ return $exists;
}
/**
function addQuotes( $s ) {
if ( $s instanceof Blob ) {
return "x'" . bin2hex( $s->fetch() ) . "'";
+ } elseif ( is_bool( $s ) ) {
+ return (int)$s;
} elseif ( strpos( $s, "\0" ) !== false ) {
// SQLite doesn't support \0 in strings, so use the hex representation as a workaround.
// This is a known limitation of SQLite's mprintf function which PDO should work around,
$out = $this->getOutput();
$missing = array();
- if ( $this->mOldRev === null ) {
+ if ( $this->mOldRev === null ||
+ ( $this->mOldRev && $this->mOldContent === null )
+ ) {
$missing[] = $this->deletedIdMarker( $this->mOldid );
}
- if ( $this->mNewRev === null ) {
+ if ( $this->mNewRev === null ||
+ ( $this->mNewRev && $this->mNewContent === null )
+ ) {
$missing[] = $this->deletedIdMarker( $this->mNewid );
}
function loadText() {
if ( $this->mTextLoaded == 2 ) {
return true;
- } else {
- // Whether it succeeds or fails, we don't want to try again
- $this->mTextLoaded = 2;
}
+ // Whether it succeeds or fails, we don't want to try again
+ $this->mTextLoaded = 2;
+
if ( !$this->loadRevisionData() ) {
return false;
}
+
if ( $this->mOldRev ) {
$this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
if ( $this->mOldContent === null ) {
return false;
}
}
+
if ( $this->mNewRev ) {
$this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
if ( $this->mNewContent === null ) {
return false;
}
}
+
return true;
}
function loadNewText() {
if ( $this->mTextLoaded >= 1 ) {
return true;
- } else {
- $this->mTextLoaded = 1;
}
+
+ $this->mTextLoaded = 1;
+
if ( !$this->loadRevisionData() ) {
return false;
}
+
$this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+
return true;
}
}
protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) {
global $wgIgnoreImageErrors;
- if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
- return $this->getHandler()->getTransform( $this, $thumbPath, $thumbUrl, $params );
+ $handler = $this->getHandler();
+ if ( $handler && $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
+ return $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
} else {
return new MediaTransformError( 'thumbnail_error',
$params['width'], 0, wfMessage( 'thumbnail-dest-create' )->text() );
/**
* Get a MediaHandler instance for this file
*
- * @return MediaHandler
+ * @return MediaHandler|boolean Registered MediaHandler for file's mime type or false if none found
*/
function getHandler() {
if ( !isset( $this->handler ) ) {
$this->load();
if ( $this->isMultipage() ) {
- $dim = $this->getHandler()->getPageDimensions( $this, $page );
+ $handler = $this->getHandler();
+ if ( !$handler ) {
+ return 0;
+ }
+ $dim = $handler->getPageDimensions( $this, $page );
if ( $dim ) {
return $dim['width'];
} else {
$this->load();
if ( $this->isMultipage() ) {
- $dim = $this->getHandler()->getPageDimensions( $this, $page );
+ $handler = $this->getHandler();
+ if ( !$handler ) {
+ return 0;
+ }
+ $dim = $handler->getPageDimensions( $this, $page );
if ( $dim ) {
return $dim['height'];
} else {
* @param array $what what updates to perform
*/
public function doUpdates( $what = array( 'core', 'extensions', 'stats' ) ) {
- global $wgVersion, $wgLocalisationCacheConf;
+ global $wgVersion;
$this->db->begin( __METHOD__ );
$what = array_flip( $what );
$this->checkStats();
}
- if ( isset( $what['purge'] ) ) {
- $this->purgeCache();
-
- if ( $wgLocalisationCacheConf['manualRecache'] ) {
- $this->rebuildLocalisationCache();
- }
- }
-
$this->setAppliedUpdates( $wgVersion, $this->updates );
if ( $this->fileHandle ) {
'config-restart' => 'Jo, neistarten',
'config-welcome' => "=== Iwwerpréifung vum Installatiounsenvironnement ===
Et gi grondsätzlech Iwwerpréifunge gemaach fir ze kucken ob den Environnment gëeegent ass fir MediaWiki z'installéieren.
-Dir sollt d'Resultater vun dëser Iwwerpréifung ugi wann Dir während der Installatioun Hëllef braucht.",
+Dir sollt d'Resultater vun dëser Iwwerpréifung ugi wann Dir während der Installatioun Hëllef frot wéi Dir D'Installatioun ofschléisse kënnt.",
'config-sidebar' => '* [//www.mediawiki.org MediaWiki Haaptsäit]
* [//www.mediawiki.org/wiki/Help:Contents Benotzerguide]
* [//www.mediawiki.org/wiki/Manual:Contents Guide fir Administrateuren]
Spezifizéiert en anere Benotzernumm.',
'config-admin-password-blank' => 'Gitt e Passwuert fir den Adminstateur-Kont an.',
'config-admin-password-same' => "D'Passwuert däerf net dat selwecht si wéi de Benotzernumm.",
- 'config-admin-password-mismatch' => 'Déi zwee Passwierder Déi dir aginn stëmmen net iwwerteneen.',
+ 'config-admin-password-mismatch' => 'Déi zwee Passwierder Déi Dir aginn hutt stëmmen net iwwereneen.',
'config-admin-email' => 'E-Mail-Adress:',
'config-admin-error-user' => 'Interne Feeler beim uleeë vun engem Administrateur mam Numm "<nowiki>$1</nowiki>".',
'config-admin-error-password' => 'Interne Feeler beim Setze vum Passwuert fir den Admin "<nowiki>$1</nowiki>": <pre>$2</pre>',
'config-help-restart' => 'Czy chcesz usunąć wszystkie zapisane dane i uruchomić ponownie proces instalacji?',
'config-restart' => 'Tak, zacznij od nowa',
'config-welcome' => '=== Sprawdzenie środowiska instalacji ===
-Wykonywane są podstawowe testy sprawdzające czy to środowisko jest odpowiednie dla instalacji MediaWiki.
-Jeśli potrzebujesz pomocy podczas instalacji załącz wyniki tych testów.',
+Teraz zostaną wykonane podstawowe testy sprawdzające czy to środowisko jest odpowiednie dla instalacji MediaWiki.
+Jeśli potrzebujesz pomocy podczas instalacji, załącz wyniki tych testów.',
'config-copyright' => "=== Prawa autorskie i warunki użytkowania ===
$1
* @author Krinkle
* @author Lockal
* @author MaxSem
+ * @author Okras
* @author Yuriy Apostol
* @author Александр Сигачёв
* @author Сrower
'config-help-restart' => 'Вы хотите удалить все сохранённые данные, которые вы ввели, и запустить процесс установки заново?',
'config-restart' => 'Да, начать заново',
'config-welcome' => '=== Проверка окружения ===
-Ð\9fÑ\80оводÑ\8fÑ\82Ñ\81Ñ\8f базовые проверки с целью определить, подходит ли данная система для установки MediaWiki.
-УкажиÑ\82е Ñ\80езÑ\83лÑ\8cÑ\82аÑ\82Ñ\8b Ñ\8dÑ\82иÑ\85 пÑ\80овеÑ\80ок пÑ\80и обÑ\80аÑ\89ении за помоÑ\89Ñ\8cÑ\8e Ñ\81 Ñ\83Ñ\81Ñ\82ановкой.',
+Ð\91Ñ\83дÑ\83Ñ\82 пÑ\80оведенÑ\8b базовые проверки с целью определить, подходит ли данная система для установки MediaWiki.
+Ð\9dе забÑ\83дÑ\8cÑ\82е вклÑ\8eÑ\87иÑ\82Ñ\8c Ñ\8dÑ\82Ñ\83 инÑ\84оÑ\80маÑ\86иÑ\8e, еÑ\81ли вам поÑ\82Ñ\80ебÑ\83еÑ\82Ñ\81Ñ\8f помоÑ\89Ñ\8c длÑ\8f завеÑ\80Ñ\88ениÑ\8f Ñ\83Ñ\81Ñ\82ановки.',
'config-copyright' => "=== Авторские права и условия ===
$1
# Wait for the DB of the current/next slave DB handle to catch up to the master.
# This way, we get the correct page_latest for templates or files that just changed
# milliseconds ago, having triggered this job to begin with.
- if ( !empty( $this->params['masterPos'] ) ) {
+ if ( isset( $this->params['masterPos'] ) && $this->params['masterPos'] !== false ) {
wfGetLB()->waitFor( $this->params['masterPos'] );
}
return $files;
}
+ /**
+ * Encode an image file as a base64 data URI.
+ * If the image file has a suitable MIME type and size, encode it as a
+ * base64 data URI. Return false if the image type is unfamiliar or exceeds
+ * the size limit.
+ *
+ * @param string $file Image file to encode.
+ * @param string|null $type File's MIME type or null. If null, CSSMin will
+ * try to autodetect the type.
+ * @param int|bool $sizeLimit If the size of the target file is greater than
+ * this value, decline to encode the image file and return false
+ * instead. If $sizeLimit is false, no limit is enforced.
+ * @return string|bool: Image contents encoded as a data URI or false.
+ */
+ public static function encodeImageAsDataURI( $file, $type = null, $sizeLimit = self::EMBED_SIZE_LIMIT ) {
+ if ( $sizeLimit !== false && filesize( $file ) >= $sizeLimit ) {
+ return false;
+ }
+ if ( $type === null ) {
+ $type = self::getMimeType( $file );
+ }
+ if ( !$type ) {
+ return false;
+ }
+ $data = base64_encode( file_get_contents( $file ) );
+ return 'data:' . $type . ';base64,' . $data;
+ }
+
/**
* @param $file string
* @return bool|string
*/
- protected static function getMimeType( $file ) {
+ public static function getMimeType( $file ) {
$realpath = realpath( $file );
// Try a couple of different ways to get the mime-type of a file, in order of
// preference
// using Z for the timezone, meaning GMT
$url .= '?' . gmdate( 'Y-m-d\TH:i:s\Z', round( filemtime( $file ), -2 ) );
// Embedding requires a bit of extra processing, so let's skip that if we can
- if ( $embedData && $embed ) {
- $type = self::getMimeType( $file );
- // Detect when URLs were preceeded with embed tags, and also verify file size is
- // below the limit
- if (
- $type
- && $match['embed'][1] > 0
- && filesize( $file ) < self::EMBED_SIZE_LIMIT
- ) {
- // Strip off any trailing = symbols (makes browsers freak out)
- $data = base64_encode( file_get_contents( $file ) );
+ if ( $embedData && $embed && $match['embed'][1] > 0 ) {
+ $data = self::encodeImageAsDataURI( $file );
+ if ( $data !== false ) {
// Build 2 CSS properties; one which uses a base64 encoded data URI in place
// of the @embed comment to try and retain line-number integrity, and the
// other with a remapped an versioned URL and an Internet Explorer hack
// making it ignored in all browsers that support data URIs
- $replacement = "{$pre}url(data:{$type};base64,{$data}){$post};";
- $replacement .= "{$pre}url({$url}){$post}!ie;";
+ $replacement = "{$pre}url({$data}){$post};{$pre}url({$url}){$post}!ie;";
}
}
if ( $replacement === false ) {
# the choices of available indexes. This mainly
# avoids site-breaking filesorts.
} elseif ( $this->title || $this->pattern || $this->performer ) {
- $index['logging'] = array( 'page_time', 'user_time' );
- if ( count( $this->types ) == 1 ) {
- $index['logging'][] = 'log_user_type_time';
- }
+ $index['logging'] = array( 'page_time', 'user_time', 'log_user_type_time' );
} elseif ( count( $this->types ) == 1 ) {
- $index['logging'] = 'type_time';
- } else {
- $index['logging'] = 'times';
+ $index['logging'] = 'type_time'; // @TODO: sucks for change tags
+ }
+ if ( count( $index ) ) {
+ $options['USE INDEX'] = $index;
}
- $options['USE INDEX'] = $index;
# Don't show duplicate rows when using log_search
$joins['log_search'] = array( 'INNER JOIN', 'ls_log_id=log_id' );
$page = $title->getPrefixedText();
$length = 0;
- if ( $title->equals( $parser->getTitle() )
- && $parser->mInputSize !== false
- ) {
- # We are on current page (and not in PST), so
- # take length of input to parser.
- $length = $parser->mInputSize;
- } elseif ( isset( $cache[$page] ) ) {
+ if ( isset( $cache[$page] ) ) {
$length = $cache[$page];
} elseif ( $parser->incrementExpensiveFunctionCount() ) {
$rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
var $mRevisionId; # ID to display in {{REVISIONID}} tags
var $mRevisionTimestamp; # The timestamp of the specified revision ID
var $mRevisionUser; # User to display in {{REVISIONUSER}} tag
+ var $mRevisionSize; # Size to display in {{REVISIONSIZE}} variable
var $mRevIdForTs; # The revision ID which was used to fetch the timestamp
var $mInputSize = false; # For {{PAGESIZE}} on current page.
$this->mLinkHolders = new LinkHolderArray( $this );
$this->mLinkID = 0;
$this->mRevisionObject = $this->mRevisionTimestamp =
- $this->mRevisionId = $this->mRevisionUser = null;
+ $this->mRevisionId = $this->mRevisionUser = $this->mRevisionSize = null;
$this->mVarCache = array();
$this->mUser = null;
$this->mLangLinkLanguages = array();
$oldRevisionObject = $this->mRevisionObject;
$oldRevisionTimestamp = $this->mRevisionTimestamp;
$oldRevisionUser = $this->mRevisionUser;
+ $oldRevisionSize = $this->mRevisionSize;
if ( $revid !== null ) {
$this->mRevisionId = $revid;
$this->mRevisionObject = null;
$this->mRevisionTimestamp = null;
$this->mRevisionUser = null;
+ $this->mRevisionSize = null;
}
wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
$this->mRevisionObject = $oldRevisionObject;
$this->mRevisionTimestamp = $oldRevisionTimestamp;
$this->mRevisionUser = $oldRevisionUser;
+ $this->mRevisionSize = $oldRevisionSize;
$this->mInputSize = false;
wfProfileOut( $fname );
wfProfileOut( __METHOD__ );
wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-revision...\n" );
$value = $this->getRevisionUser();
break;
+ case 'revisionsize':
+ # Let the edit saving system know we should parse the page
+ # *after* a revision ID has been assigned. This is for null edits.
+ $this->mOutput->setFlag( 'vary-revision' );
+ wfDebug( __METHOD__ . ": {{REVISIONSIZE}} used, setting vary-revision...\n" );
+ $value = $this->getRevisionSize();
+ break;
case 'namespace':
$value = str_replace( '_', ' ', $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
break;
return $this->mRevisionUser;
}
+ /**
+ * Get the size of the revision
+ *
+ * @return int|null revision size
+ */
+ function getRevisionSize() {
+ if ( is_null( $this->mRevisionSize ) ) {
+ $revObject = $this->getRevisionObject();
+
+ # if this variable is subst: the revision id will be blank,
+ # so just use the parser input size, because the own substituation
+ # will change the size.
+ if ( $revObject ) {
+ $this->mRevisionSize = $revObject->getSize();
+ } elseif ( $this->ot['wiki'] || $this->mOptions->getIsPreview() ) {
+ $this->mRevisionSize = $this->mInputSize;
+ }
+ }
+ return $this->mRevisionSize;
+ }
+
/**
* Mutator for $mDefaultSort
*
$xml = UtfNormal::cleanUp( $xml );
// 1 << 19 == XML_PARSE_HUGE, needed so newer versions of libxml2 don't barf when the XML is >256 levels deep
$result = $dom->loadXML( $xml, 1 << 19 );
- if ( !$result ) {
- wfProfileOut( __METHOD__ . '-loadXML' );
- if ( $cacheable ) {
- wfProfileOut( __METHOD__ . '-cacheable' );
- }
- wfProfileOut( __METHOD__ );
- throw new MWException( __METHOD__ . ' generated invalid XML' );
- }
}
- $obj = new PPNode_DOM( $dom->documentElement );
+ if ( $result ) {
+ $obj = new PPNode_DOM( $dom->documentElement );
+ }
wfProfileOut( __METHOD__ . '-loadXML' );
+
if ( $cacheable ) {
wfProfileOut( __METHOD__ . '-cacheable' );
}
+
wfProfileOut( __METHOD__ );
+
+ if ( !$result ) {
+ throw new MWException( __METHOD__ . ' generated invalid XML' );
+ }
return $obj;
}
$cache = wfGetCache( CACHE_ANYTHING );
$cacheEntry = $cache->get( $key );
if ( is_string( $cacheEntry ) ) {
+ wfIncrStats( "rl-$filter-cache-hits" );
wfProfileOut( __METHOD__ );
return $cacheEntry;
}
$result = '';
// Run the filter - we've already verified one of these will work
try {
+ wfIncrStats( "rl-$filter-cache-misses" );
switch ( $filter ) {
case 'minify-js':
$result = JavaScriptMinifier::minify( $data,
// Save filtered text to Memcached
$cache->set( $key, $result );
} catch ( Exception $exception ) {
+ $exception->logException();
wfDebugLog( 'resourceloader', __METHOD__ . ": minification failed: $exception" );
$this->hasErrors = true;
// Return exception as a comment
try {
$this->preloadModuleInfo( array_keys( $modules ), $context );
} catch ( Exception $e ) {
+ $e->logException();
wfDebugLog( 'resourceloader', __METHOD__ . ": preloading module info failed: $e" );
$this->hasErrors = true;
// Add exception to the output as a comment
// Calculate maximum modified time
$mtime = max( $mtime, $module->getModifiedTime( $context ) );
} catch ( Exception $e ) {
+ $e->logException();
wfDebugLog( 'resourceloader', __METHOD__ . ": calculating maximum modified time failed: $e" );
$this->hasErrors = true;
// Add exception to the output as a comment
// See also http://bugs.php.net/bug.php?id=51579
// To work around this, we tear down all output buffering before
// sending the 304.
- // On some setups, ob_get_level() doesn't seem to go down to zero
- // no matter how often we call ob_get_clean(), so instead of doing
- // the more intuitive while ( ob_get_level() > 0 ) ob_get_clean();
- // we have to be safe here and avoid an infinite loop.
- // Caching the level is not an option, need to allow it to
- // shorten the loop on-the-fly (bug 46836)
- for ( $i = 0; $i < ob_get_level(); $i++ ) {
- ob_end_clean();
- }
+ wfResetOutputBuffers( /* $resetGzipEncoding = */ true );
header( 'HTTP/1.0 304 Not Modified' );
header( 'Status: 304 Not Modified' );
try {
$blobs = MessageBlobStore::get( $this, $modules, $context->getLanguage() );
} catch ( Exception $e ) {
+ $e->logException();
wfDebugLog( 'resourceloader', __METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e" );
$this->hasErrors = true;
// Add exception to the output as a comment
break;
}
} catch ( Exception $e ) {
+ $e->logException();
wfDebugLog( 'resourceloader', __METHOD__ . ": generating module package failed: $e" );
$this->hasErrors = true;
// Add exception to the output as a comment
return 'rev_id';
}
+ public static function getRestriction() {
+ return 'deleterevision';
+ }
+
+ public static function getRevdelConstant() {
+ return Revision::DELETED_TEXT;
+ }
+
+ public static function suggestTarget( $target, array $ids ) {
+ $rev = Revision::newFromId( $ids[0] );
+ return $rev ? $rev->getTitle() : $target;
+ }
+
/**
* @param $db DatabaseBase
* @return mixed
return 'oi_archive_name';
}
+ public static function getRestriction() {
+ return 'deleterevision';
+ }
+
+ public static function getRevdelConstant() {
+ return File::DELETED_FILE;
+ }
+
var $storeBatch, $deleteBatch, $cleanupBatch;
/**
return 'log_id';
}
+ public static function getRestriction() {
+ return 'deletelogentry';
+ }
+
+ public static function getRevdelConstant() {
+ return LogPage::DELETED_ACTION;
+ }
+
+ public static function suggestTarget( $target, array $ids ) {
+ $result = wfGetDB( DB_SLAVE )->select( 'logging',
+ 'log_type',
+ array( 'log_id' => $ids ),
+ __METHOD__,
+ array( 'DISTINCT' )
+ );
+ if ( $result->numRows() == 1 ) {
+ // If there's only one type, the target can be set to include it.
+ return SpecialPage::getTitleFor( 'Log', $result->current()->log_type );
+ }
+ return SpecialPage::getTitleFor( 'Log' );
+ }
+
/**
* @param $db DatabaseBase
* @return mixed
* Get the DB field name associated with the ID list.
* This used to populate the log_search table for finding log entries.
* Override this function.
- * @return null
+ * @return string|null
*/
public static function getRelationType() {
return null;
}
+ /**
+ * Get the user right required for this list type
+ * Override this function.
+ * @since 1.22
+ * @return string|null
+ */
+ public static function getRestriction() {
+ return null;
+ }
+
+ /**
+ * Get the revision deletion constant for this list type
+ * Override this function.
+ * @since 1.22
+ * @return int|null
+ */
+ public static function getRevdelConstant() {
+ return null;
+ }
+
+ /**
+ * Suggest a target for the revision deletion
+ * Optionally override this function.
+ * @since 1.22
+ * @param Title|null $target User-supplied target
+ * @param array $ids
+ * @return Title|null
+ */
+ public static function suggestTarget( $target, array $ids ) {
+ return $target;
+ }
+
/**
* Set the visibility for the revisions in this list. Logging and
* transactions are done here.
$oldBits = $item->getBits();
// Build the actual new rev_deleted bitfield
- $newBits = SpecialRevisionDelete::extractBitfield( $bitPars, $oldBits );
+ $newBits = RevisionDeleter::extractBitfield( $bitPars, $oldBits );
if ( $oldBits == $newBits ) {
$status->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
*/
/**
- * Temporary b/c interface, collection of static functions.
- * @ingroup SpecialPage
+ * General controller for RevDel, used by both SpecialRevisiondelete and
+ * ApiRevisionDelete.
* @ingroup RevisionDelete
*/
class RevisionDeleter {
+ /** List of known revdel types, with their corresponding list classes */
+ private static $allowedTypes = array(
+ 'revision' => 'RevDel_RevisionList',
+ 'archive' => 'RevDel_ArchiveList',
+ 'oldimage' => 'RevDel_FileList',
+ 'filearchive' => 'RevDel_ArchivedFileList',
+ 'logging' => 'RevDel_LogList',
+ );
+
+ /** Type map to support old log entries */
+ private static $deprecatedTypeMap = array(
+ 'oldid' => 'revision',
+ 'artimestamp' => 'archive',
+ 'oldimage' => 'oldimage',
+ 'fileid' => 'filearchive',
+ 'logid' => 'logging',
+ );
+
+ /**
+ * Lists the valid possible types for revision deletion.
+ *
+ * @since 1.22
+ * @return array
+ */
+ public static function getTypes() {
+ return array_keys( self::$allowedTypes );
+ }
+
+ /**
+ * Gets the canonical type name, if any.
+ *
+ * @since 1.22
+ * @param string $typeName
+ * @return string|null
+ */
+ public static function getCanonicalTypeName( $typeName ) {
+ if ( isset( self::$deprecatedTypeMap[$typeName] ) ) {
+ $typeName = self::$deprecatedTypeMap[$typeName];
+ }
+ return isset( self::$allowedTypes[$typeName] ) ? $typeName : null;
+ }
+
+ /**
+ * Instantiate the appropriate list class for a given list of IDs.
+ *
+ * @since 1.22
+ * @param string $typeName RevDel type, see RevisionDeleter::getTypes()
+ * @param IContextSource $context
+ * @param Title $title
+ * @param array $ids
+ * @return RevDel_List
+ */
+ public static function createList( $typeName, IContextSource $context, Title $title, array $ids ) {
+ $typeName = self::getCanonicalTypeName( $typeName );
+ if ( !$typeName ) {
+ throw new MWException( __METHOD__ . ": Unknown RevDel type '$typeName'" );
+ }
+ return new self::$allowedTypes[$typeName]( $context, $title, $ids );
+ }
+
/**
* Checks for a change in the bitfield for a certain option and updates the
* provided array accordingly.
/** Get DB field name for URL param...
* Future code for other things may also track
* other types of revision-specific changes.
+ * @param string $typeName
* @return string One of log_id/rev_id/fa_id/ar_timestamp/oi_archive_name
*/
public static function getRelationType( $typeName ) {
- if ( isset( SpecialRevisionDelete::$deprecatedTypeMap[$typeName] ) ) {
- $typeName = SpecialRevisionDelete::$deprecatedTypeMap[$typeName];
+ $typeName = self::getCanonicalTypeName( $typeName );
+ if ( !$typeName ) {
+ return null;
+ }
+ return call_user_func( array( self::$allowedTypes[$typeName], 'getRelationType' ) );
+ }
+
+ /**
+ * Get the user right required for the RevDel type
+ * @since 1.22
+ * @param string $typeName
+ * @return string User right
+ */
+ public static function getRestriction( $typeName ) {
+ $typeName = self::getCanonicalTypeName( $typeName );
+ if ( !$typeName ) {
+ return null;
}
- if ( isset( SpecialRevisionDelete::$allowedTypes[$typeName] ) ) {
- $class = SpecialRevisionDelete::$allowedTypes[$typeName]['list-class'];
- return call_user_func( array( $class, 'getRelationType' ) );
- } else {
+ return call_user_func( array( self::$allowedTypes[$typeName], 'getRestriction' ) );
+ }
+
+ /**
+ * Get the revision deletion constant for the RevDel type
+ * @since 1.22
+ * @param string $typeName
+ * @return int RevDel constant
+ */
+ public static function getRevdelConstant( $typeName ) {
+ $typeName = self::getCanonicalTypeName( $typeName );
+ if ( !$typeName ) {
return null;
}
+ return call_user_func( array( self::$allowedTypes[$typeName], 'getRevdelConstant' ) );
}
+ /**
+ * Suggest a target for the revision deletion
+ * @since 1.22
+ * @param string $typeName
+ * @param Title|null $title User-supplied target
+ * @param array $ids
+ * @return Title|null
+ */
+ public static function suggestTarget( $typeName, $target, array $ids ) {
+ $typeName = self::getCanonicalTypeName( $typeName );
+ if ( !$typeName ) {
+ return $target;
+ }
+ return call_user_func( array( self::$allowedTypes[$typeName], 'suggestTarget' ), $target, $ids );
+ }
+
+
/**
* Checks if a revision still exists in the revision table.
* If it doesn't, returns the corresponding ar_timestamp field
return $timestamp;
}
+
+ /**
+ * Put together a rev_deleted bitfield
+ * @since 1.22
+ * @param array $bitPars extractBitParams() params
+ * @param int $oldfield current bitfield
+ * @return array
+ */
+ public static function extractBitfield( $bitPars, $oldfield ) {
+ // Build the actual new rev_deleted bitfield
+ $newBits = 0;
+ foreach ( $bitPars as $const => $val ) {
+ if ( $val == 1 ) {
+ $newBits |= $const; // $const is the *_deleted const
+ } elseif ( $val == -1 ) {
+ $newBits |= ( $oldfield & $const ); // use existing
+ }
+ }
+ return $newBits;
+ }
}
* @return String: highlighted text snippet, null (and not '') if not supported
*/
function getTextSnippet( $terms ) {
- global $wgUser, $wgAdvancedSearchHighlighting;
+ global $wgAdvancedSearchHighlighting;
$this->initText();
// TODO: make highliter take a content object. Make ContentHandler a factory for SearchHighliter.
- list( $contextlines, $contextchars ) = SearchEngine::userHighlightPrefs( $wgUser );
+ list( $contextlines, $contextchars ) = SearchEngine::userHighlightPrefs();
$h = new SearchHighlighter();
if ( $wgAdvancedSearchHighlighting ) {
return $h->highlightText( $this->mText, $terms, $contextlines, $contextchars );
return $site;
}
+ /**
+ * Get a new ORMRow from a Site object
+ *
+ * @since 1.22
+ *
+ * @param Site
+ *
+ * @return ORMRow
+ */
+ protected function getRowFromSite( Site $site ) {
+ $fields = array(
+ // Site data
+ 'global_key' => $site->getGlobalId(), // TODO: check not null
+ 'type' => $site->getType(),
+ 'group' => $site->getGroup(),
+ 'source' => $site->getSource(),
+ 'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
+ 'protocol' => $site->getProtocol(),
+ 'domain' => strrev( $site->getDomain() ) . '.',
+ 'data' => $site->getExtraData(),
+
+ // Site config
+ 'forward' => $site->shouldForward(),
+ 'config' => $site->getExtraConfig(),
+ );
+
+ if ( $site->getInternalId() !== null ) {
+ $fields['id'] = $site->getInternalId();
+ }
+
+ return new ORMRow( $this->sitesTable, $fields );
+ }
+
/**
* Fetches the site from the database and loads them into the sites field.
*
$localIds = array();
foreach ( $sites as $site ) {
- $fields = array(
- // Site data
- 'global_key' => $site->getGlobalId(), // TODO: check not null
- 'type' => $site->getType(),
- 'group' => $site->getGroup(),
- 'source' => $site->getSource(),
- 'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
- 'protocol' => $site->getProtocol(),
- 'domain' => strrev( $site->getDomain() ) . '.',
- 'data' => $site->getExtraData(),
-
- // Site config
- 'forward' => $site->shouldForward(),
- 'config' => $site->getExtraConfig(),
- );
-
if ( $site->getInternalId() !== null ) {
- $fields['id'] = $site->getInternalId();
$internalIds[] = $site->getInternalId();
}
- $siteRow = new ORMRow( $this->sitesTable, $fields );
+ $siteRow = $this->getRowFromSite( $site );
$success = $siteRow->save( __METHOD__ ) && $success;
foreach ( $site->getLocalIds() as $idType => $ids ) {
/** Array of checkbox specs (message, name, deletion bits) */
var $checks;
- /** Information about the current type */
- var $typeInfo;
+ /** UI Labels about the current type */
+ var $typeLabels;
/** The RevDel_List object, storing the list of items to be deleted/undeleted */
var $list;
/**
- * Assorted information about each type, needed by the special page.
- * TODO Move some of this to the list class
+ * UI labels for each type.
*/
- static $allowedTypes = array(
+ static $UILabels = array(
'revision' => array(
'check-label' => 'revdelete-hide-text',
- 'deletion-bits' => Revision::DELETED_TEXT,
'success' => 'revdelete-success',
'failure' => 'revdelete-failure',
- 'list-class' => 'RevDel_RevisionList',
- 'permission' => 'deleterevision',
),
'archive' => array(
'check-label' => 'revdelete-hide-text',
- 'deletion-bits' => Revision::DELETED_TEXT,
'success' => 'revdelete-success',
'failure' => 'revdelete-failure',
- 'list-class' => 'RevDel_ArchiveList',
- 'permission' => 'deleterevision',
),
'oldimage' => array(
'check-label' => 'revdelete-hide-image',
- 'deletion-bits' => File::DELETED_FILE,
'success' => 'revdelete-success',
'failure' => 'revdelete-failure',
- 'list-class' => 'RevDel_FileList',
- 'permission' => 'deleterevision',
),
'filearchive' => array(
'check-label' => 'revdelete-hide-image',
- 'deletion-bits' => File::DELETED_FILE,
'success' => 'revdelete-success',
'failure' => 'revdelete-failure',
- 'list-class' => 'RevDel_ArchivedFileList',
- 'permission' => 'deleterevision',
),
'logging' => array(
'check-label' => 'revdelete-hide-name',
- 'deletion-bits' => LogPage::DELETED_ACTION,
'success' => 'logdelete-success',
'failure' => 'logdelete-failure',
- 'list-class' => 'RevDel_LogList',
- 'permission' => 'deletelogentry',
),
);
- /** Type map to support old log entries */
- static $deprecatedTypeMap = array(
- 'oldid' => 'revision',
- 'artimestamp' => 'archive',
- 'oldimage' => 'oldimage',
- 'fileid' => 'filearchive',
- 'logid' => 'logging',
- );
-
public function __construct() {
parent::__construct( 'Revisiondelete', 'deletedhistory' );
}
} else {
$this->typeName = $request->getVal( 'type' );
$this->targetObj = Title::newFromText( $request->getText( 'target' ) );
- if ( $this->targetObj && $this->targetObj->isSpecial( 'Log' ) && count( $this->ids ) !== 0 ) {
- $result = wfGetDB( DB_SLAVE )->select( 'logging',
- 'log_type',
- array( 'log_id' => $this->ids ),
- __METHOD__,
- array( 'DISTINCT' )
- );
-
- if ( $result->numRows() == 1 ) {
- // If there's only one type, the target can be set to include it.
- $this->targetObj = SpecialPage::getTitleFor( 'Log', $result->current()->log_type );
- }
- }
}
# For reviewing deleted files...
return;
}
- if ( isset( self::$deprecatedTypeMap[$this->typeName] ) ) {
- $this->typeName = self::$deprecatedTypeMap[$this->typeName];
- }
+ $this->typeName = RevisionDeleter::getCanonicalTypeName( $this->typeName );
# No targets?
- if ( !isset( self::$allowedTypes[$this->typeName] ) || count( $this->ids ) == 0 ) {
+ if ( !$this->typeName || count( $this->ids ) == 0 ) {
throw new ErrorPageError( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
}
- $this->typeInfo = self::$allowedTypes[$this->typeName];
- $this->mIsAllowed = $user->isAllowed( $this->typeInfo['permission'] );
-
- # If we have revisions, get the title from the first one
- # since they should all be from the same page. This allows
- # for more flexibility with page moves...
- if ( $this->typeName == 'revision' ) {
- $rev = Revision::newFromId( $this->ids[0] );
- $this->targetObj = $rev ? $rev->getTitle() : $this->targetObj;
- }
+ $this->typeLabels = self::$UILabels[$this->typeName];
+ $this->mIsAllowed = $user->isAllowed( RevisionDeleter::getRestriction( $this->typeName ) );
+
+ # Allow the list type to adjust the passed target
+ $this->targetObj = RevisionDeleter::suggestTarget( $this->typeName, $this->targetObj, $this->ids );
$this->otherReason = $request->getVal( 'wpReason' );
# We need a target page!
# Initialise checkboxes
$this->checks = array(
- array( $this->typeInfo['check-label'], 'wpHidePrimary', $this->typeInfo['deletion-bits'] ),
+ array( $this->typeLabels['check-label'], 'wpHidePrimary',
+ RevisionDeleter::getRevdelConstant( $this->typeName )
+ ),
array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER )
);
*/
protected function getList() {
if ( is_null( $this->list ) ) {
- $class = $this->typeInfo['list-class'];
- $this->list = new $class( $this->getContext(), $this->targetObj, $this->ids );
+ $this->list = RevisionDeleter::createList(
+ $this->typeName, $this->getContext(), $this->targetObj, $this->ids
+ );
}
return $this->list;
}
*/
protected function success() {
$this->getOutput()->setPageTitle( $this->msg( 'actioncomplete' ) );
- $this->getOutput()->wrapWikiMsg( "<span class=\"success\">\n$1\n</span>", $this->typeInfo['success'] );
+ $this->getOutput()->wrapWikiMsg( "<span class=\"success\">\n$1\n</span>", $this->typeLabels['success'] );
$this->list->reloadFromMaster();
$this->showForm();
}
*/
protected function failure( $status ) {
$this->getOutput()->setPageTitle( $this->msg( 'actionfailed' ) );
- $this->getOutput()->addWikiText( $status->getWikiText( $this->typeInfo['failure'] ) );
+ $this->getOutput()->addWikiText( $status->getWikiText( $this->typeLabels['failure'] ) );
$this->showForm();
}
/**
* Put together a rev_deleted bitfield
+ * @deprecated since 1.22, use RevisionDeleter::extractBitfield instead
* @param array $bitPars extractBitParams() params
* @param int $oldfield current bitfield
* @return array
*/
public static function extractBitfield( $bitPars, $oldfield ) {
- // Build the actual new rev_deleted bitfield
- $newBits = 0;
- foreach ( $bitPars as $const => $val ) {
- if ( $val == 1 ) {
- $newBits |= $const; // $const is the *_deleted const
- } elseif ( $val == -1 ) {
- $newBits |= ( $oldfield & $const ); // use existing
- }
- }
- return $newBits;
+ return RevisionDeleter::extractBitfield( $bitPars, $oldfield );
}
/**
Xml::tags( 'th', null, $this->msg( 'tags-description-header' )->parse() ) .
Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() )
);
- $dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( 'change_tag', array( 'ct_tag', 'hitcount' => 'count(*)' ),
- array(), __METHOD__, array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) );
- foreach ( $res as $row ) {
- $html .= $this->doTagRow( $row->ct_tag, $row->hitcount );
- }
-
- foreach ( ChangeTags::listDefinedTags() as $tag ) {
- $html .= $this->doTagRow( $tag, 0 );
+ foreach ( ChangeTags::tagUsageStatistics() as $tag => $hitcount ) {
+ $html .= $this->doTagRow( $tag, $hitcount );
}
$out->addHTML( Xml::tags( 'table', array( 'class' => 'wikitable sortable mw-tags-table' ), $html ) );
}
function doTagRow( $tag, $hitcount ) {
- static $doneTags = array();
-
- if ( in_array( $tag, $doneTags ) ) {
- return '';
- }
-
$user = $this->getUser();
$newRow = '';
$newRow .= Xml::tags( 'td', null, Xml::element( 'code', null, $tag ) );
// add raw $hitcount for sorting, because tags-hitcount contains numbers and letters
$newRow .= Xml::tags( 'td', array( 'data-sort-value' => $hitcount ), $hitcountLink );
- $doneTags[] = $tag;
-
return Xml::tags( 'tr', null, $newRow ) . "\n";
}
$paramString = substr( $thumbPart, 0, $srcNamePos - 1 );
$handler = $file->getHandler();
- $params = $handler->parseParamString( $paramString );
- return array( 'file' => $file, 'type' => $type, 'params' => $params );
+ if ( $handler ) {
+ $params = $handler->parseParamString( $paramString );
+ return array( 'file' => $file, 'type' => $type, 'params' => $params );
+ } else {
+ throw new UploadStashBadPathException( 'No handler found for ' .
+ "mime {$file->getMimeType()} of file {$file->getPath()}" );
+ }
}
return array( 'file' => $file, 'type' => $type );
// Timestamp within the past week: show the day of the week and time
$format = $this->getDateFormatString( 'time', $user->getDatePreference() ?: 'default' );
$weekday = self::$mWeekdayMsgs[$ts->timestamp->format( 'w' )];
+ // Messages:
+ // sunday-at, monday-at, tuesday-at, wednesday-at, thursday-at, friday-at, saturday-at
$ts = wfMessage( "$weekday-at" )
->inLanguage( $this )
->params( $this->sprintfDate( $format, $ts->getTimestamp( TS_MW ) ) )
'tog-extendwatchlist' => 'مدد قائمة المراقبة لتعرض كل التغييرات، وليس أحدثها فقط',
'tog-usenewrc' => 'جمّع التغييرات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت)',
'tog-numberheadings' => 'رقّم العناوين تلقائيًا',
-'tog-showtoolbar' => 'أظهر شريط التحرير (يتطلب جافاسكربت)',
-'tog-editondblclick' => 'تحرير الصفحات بالنقر المزدوج (جافاسكربت)',
+'tog-showtoolbar' => 'أظهر شريط التحرير',
+'tog-editondblclick' => 'تحرير الصفحات بالنقر المزدوج',
'tog-editsection' => 'مكن تحرير الأقسام بروابط [عدل]',
'tog-editsectiononrightclick' => 'فعِّل تحرير الأقسام بالنقر باليمين على عناوين الأقسام (يتطلب جافاسكريبت)',
'tog-showtoc' => 'اعرض فهرس المحتويات (للصفحات التي تحتوي على أكثر من 3 عناوين)',
'tog-shownumberswatching' => 'اعرض عدد المستخدمين المراقبِين',
'tog-oldsig' => 'التوقيع الحالي:',
'tog-fancysig' => 'عامل التوقيع كنصّ ويكي (بلا رابط تلقائي)',
-'tog-uselivepreview' => 'استخدÙ\85 اÙ\84Ù\85عاÙ\8aÙ\86Ø© اÙ\84سرÙ\8aعة (تتطÙ\84ب جاÙ\81اسÙ\83رÙ\8aبت) (تجريبية)',
+'tog-uselivepreview' => 'إستخدÙ\85 اÙ\84Ù\85عاÙ\8aÙ\86Ø© اÙ\84ØÙ\8aØ©(تجريبية)',
'tog-forceeditsummary' => 'نبهني عند إدخال ملخص تحرير فارغ',
'tog-watchlisthideown' => 'أخف تحريراتي من قائمة المراقبة',
'tog-watchlisthidebots' => 'أخف تحريرات الروبوتات من قائمة المراقبة',
# Categories related messages
'pagecategories' => '{{PLURAL:$1|بلا تصنيف|تصنيف|تصنيفان|تصنيفات}}',
-'category_header' => 'اÙ\84صÙ\81Øات Ù\81Ù\8a اÙ\84تصنيف "$1"',
+'category_header' => 'صÙ\81Øات تصنيف "$1"',
'subcategories' => 'تصنيفات فرعية',
-'category-media-header' => 'الوسائط في التصنيف "$1"',
-'category-empty' => "''هذا التصنيف لا يحتوي حاليا على صفحات و لا وسائط.''",
+'category-media-header' => 'ملفات تصنيف "$1"',
+'category-empty' => 'هذا التصنيف لا يحتوي حاليا على صفحات أو ملفات.',
'hidden-categories' => '{{PLURAL:$1|لا تصنيفات مخفية|تصنيف مخفي|تصنيفان مخفيان|تصنيفات مخفية}}',
'hidden-category-category' => 'تصنيفات مخفية',
'category-subcat-count' => '{{PLURAL:$2|هذا التصنيف يحوي التصنيف الفرعي التالي|هذا التصنيف يحوي {{PLURAL:$1||التصنيف الفرعي|تصنيفين فرعيين|$1 تصنيفات فرعية}}، من إجمالي $2.}}',
'histfirst' => 'الأقدم',
'histlast' => 'الأحدث',
'historysize' => '({{PLURAL:$1|1 بايت|$1 بايت}})',
-'historyempty' => '(فارغ)',
+'historyempty' => '(فارغة)',
# Revision feed
'history-feed-title' => 'تاريخ المراجعة',
'prefs-rendering' => 'المظهر',
'saveprefs' => 'احفظ',
'resetprefs' => 'أزل التغييرات غير المحفوظة',
-'restoreprefs' => 'استرجع كل الإعدادات الافتراضية',
+'restoreprefs' => 'Ø¥سترجع كل الإعدادات الافتراضية',
'prefs-editing' => 'التحرير',
'rows' => 'صفوف:',
'columns' => 'أعمدة:',
'prefs-displaywatchlist' => 'خصائص العرض',
'prefs-tokenwatchlist' => 'مفتاح',
'prefs-diffs' => 'فروقات',
+'prefs-help-prefershttps' => 'سيتم تفعيل هذا التفضيل عند ولوجوك في المرة القادمة.',
# User preference: email validation using jQuery
'email-address-validity-valid' => 'يبدو أن عنوان البريد الإلكتروني صالح',
'right-editmyusercss' => 'تعديل ملفات CSS للمستخدم نفسه',
'right-editmyuserjs' => 'تعديل ملفات جافاسكربت للمستخدم نفسه',
'right-viewmywatchlist' => 'عرض قائمة مراقبتك',
+'right-viewmyprivateinfo' => 'إستعرض بياناتك الشخصية (مثل البريد الإلكتروني والإسم الحقيقي)',
+'right-editmyprivateinfo' => 'حرر بياناتك الشخصية (مثل البريد الإلكتروني والإسم الحقيقي)',
'right-editmyoptions' => 'تعديل تفضيلاتك',
'right-rollback' => 'استرجاع تعديلات آخر مستخدم عدل صفحة معينة سريعا',
'right-markbotedits' => 'التعليم على تعديلات الاسترجاع كتعديلات بوت',
# Recent changes
'nchanges' => '{{PLURAL:$1|لا تغييرات|تغيير واحد|تغييران|$1 تغييرات|$1 تغييرا|$1 تغيير}}',
+'enhancedrc-since-last-visit' => '$1 {{PLURAL:$1|منذ الزيارة الأخيرة}}',
'enhancedrc-history' => 'تاريخ',
'recentchanges' => 'أحدث التغييرات',
'recentchanges-legend' => 'خيارات أحدث التغييرات',
'rc_categories_any' => 'أي',
'rc-change-size-new' => '$1 {{PLURAL:$1|بايت|بايت}} بعد التغيير',
'newsectionsummary' => '/* $1 */ قسم جديد',
-'rc-enhanced-expand' => 'عرض التفاصيل (يتطلب جافاسكريبت)',
+'rc-enhanced-expand' => 'عرض التفاصيل',
'rc-enhanced-hide' => 'أخفِ التفاصيل',
'rc-old-title' => 'تم إنشاؤها أصلا ك"$1"',
'upload_source_file' => ' (ملف على حاسوبك)',
# Special:ListFiles
-'listfiles-summary' => 'هذه الصفحة الخاصة تعرض كل الملفات المرفوعة.
-عندما ترشحها حسب المستخدم ستعرض فقط الملفات التي رفع آخر نسخة منها ذلك المستخدم.',
+'listfiles-summary' => 'هذه الصفحة الخاصة تعرض كل الملفات المرفوعة.',
'listfiles_search_for' => 'ابحث عن اسم الميديا:',
'imgfile' => 'ملف',
'listfiles' => 'قائمة الملفات',
'listfiles_size' => 'الحجم',
'listfiles_description' => 'الوصف',
'listfiles_count' => 'نسخ',
+'listfiles-show-all' => 'أدرج النسخ القديمة من الصور',
+'listfiles-latestversion' => 'النسخة الحالية',
+'listfiles-latestversion-yes' => 'نعم',
+'listfiles-latestversion-no' => 'لا',
# File description page
'file-anchor-link' => 'ملف',
# Random page in category
'randomincategory' => 'صفحة عشوائية في التصنيف',
'randomincategory-invalidcategory' => '"$1" ليس اسم تصنيف صالح.',
+'randomincategory-nopages' => 'لا توجد صفحات في التصنيف [[:Category:$1|$1]].',
'randomincategory-selectcategory' => 'عرض صفحة عشوائية من التصنيف: $1 $2',
'randomincategory-selectcategory-submit' => 'اذهب',
'compare-selector' => 'قارن مراجعات الصفحة',
'compare-page1' => 'صفحة 1',
'compare-page2' => 'صفحة 2',
-'compare-rev1' => 'Ù\85راجعة 1',
-'compare-rev2' => 'Ù\85راجعة 2',
+'compare-rev1' => 'Ù\86سخة 1',
+'compare-rev2' => 'Ù\86سخة 2',
'compare-submit' => 'قارن',
'compare-invalid-title' => 'العنوان الذي حددته غير متاح.',
'compare-title-not-exists' => 'العنوان الذي حددته غير موجود.',
'dberr-problems' => 'عذرا! هذا الموقع يعاني من صعوبات تقنية.',
'dberr-again' => 'جرب الانتظار بضع دقائق وإعادة التحميل.',
'dberr-info' => '(غير قادر على الاتصال بخادوم قاعدة البيانات: $1)',
+'dberr-info-hidden' => '(لا يمكن الإتصال بخادم قاعدة البيانات)',
'dberr-usegoogle' => 'يمكنك محاولة البحث من خلال جوجل في الوقت الحاضر.',
'dberr-outofdate' => 'لاحظ أن فهارسهم لمحتوانا ربما تكون غير محدثة.',
'dberr-cachederror' => 'التالي نسخة مخزنة من الصفحة المطلوبة، وربما لا تكون محدثة.',
'rotate-comment' => 'تدوير الصورة {{PLURAL:$1||درجة واحدة|درجتان|$1 درجات|$1 درجة}} باتجاه عقارب الساعة',
# Limit report
+'limitreport-cputime' => 'بيانات إستخدام وحدة المعالجة المركزية',
'limitreport-cputime-value' => '{{PLURAL:$1|أقل من ثانية|ثانية واحدة|ثانيتان|$1 ثوانٍ|$1 ثانية}}',
+'limitreport-walltime' => 'بيانات الإستخدام الآني',
'limitreport-walltime-value' => '{{PLURAL:$1|أقل من ثانية|ثانية واحدة|ثانيتان|$1 ثوانٍ|$1 ثانية}}',
+'limitreport-postexpandincludesize-value' => '$1/$2 بايت',
+'limitreport-templateargumentsize-value' => '$1/$2 بايت',
);
'tog-hidepatrolled' => 'Tagóa an patrolyadong mga paghirá sa nakakaági pa sanáng pagbabàgo',
'tog-newpageshidepatrolled' => 'Tagóa an patrolyadong mga pahina gikan sa listahan kan bàgong pahina',
'tog-extendwatchlist' => 'Palakbanga an bantay-listahan (watchlist) na maipahiling an gabos na pinagbago, bako sana an pinakahurihang binago',
-'tog-usenewrc' => 'Grupong mga pagbabago sa kada pahina kan pinakahuring mga binago asin bantay-listahan (minakaipo nin JavaScript)',
+'tog-usenewrc' => 'Pangrupong mga kaliwatan sa kada pahina kan mga dae pa sana nahaloy na mga kaliwatan asin bantay-listahan',
'tog-numberheadings' => 'Tolos-bilang na mga pamayohán',
-'tog-showtoolbar' => 'Ihayag an toolbar nin paghirá (minakaipo nin JavaScript)',
-'tog-editondblclick' => 'Liwaton an mga pahina sa dobleng pagpindot (minakaipo nin JavaScript)',
+'tog-showtoolbar' => 'Ipahiling an barang-gamit nin pagliwat',
+'tog-editondblclick' => 'Liwaton an mga pahina sa pagdoble nin klik',
'tog-editsection' => 'Paganaha an paghihirá kan seksyon sa paági kan [liwaton] na kilyawan',
-'tog-editsectiononrightclick' => 'Paganaha an paghihirá kan seksyon sa paagi kan patoong pagpindot sa mga titulo kan seksyon (minakaipo nin JavaScript)',
+'tog-editsectiononrightclick' => 'Paganaha an seksyon nin pagliliwat sa pag-klik kan mga titulo nin seksyon',
'tog-showtoc' => 'Ihayag an taytayan nin mga laog (para sa mga pahinang igwang sobra sa 3 pamayohan)',
'tog-rememberpassword' => 'Giromdoma an sakong paglaóg sa kilyaw (browser) na ini (para sa maximum na $1 {{PLURAL:$1|aldaw|mga aldaw}})',
'tog-watchcreations' => 'Idagdag an mga pahina na ako an nagmukna asin an mga sagunson na ako an nagkarga sa sakong bantay-listahan',
'tog-shownumberswatching' => 'Ihayag an numero kan nagbabantay na mga parágamit',
'tog-oldsig' => 'Tugmadong pirma',
'tog-fancysig' => 'Trataron an pirma na wiki-teksto (mayo nin awtomatikong kilyaw)',
-'tog-uselivepreview' => 'Gamíta an buhay na patànaw (minakaipo nin JavaScript) (eksperimental)',
+'tog-uselivepreview' => 'Gamíta an buhay na patànaw (eksperimental)',
'tog-forceeditsummary' => 'Ibunyaw sako kun maglalaog sa blangkong kalanyang nin paghirá',
'tog-watchlisthideown' => 'Tagóa an sakong mga pagliwat gikan sa bantay-listahan',
'tog-watchlisthidebots' => 'Tagóa an bot na mga pagliwat gikan sa bantay-listahan',
'newwindow' => '(minabukas sa bàgong bintanà)',
'cancel' => 'Kanselaron',
'moredotdotdot' => 'Kadagdagan...',
-'morenotlisted' => 'Dakol pa an bakong listado...',
+'morenotlisted' => 'Ining listahan bako pang kumpleto.',
'mypage' => 'An Pahina',
'mytalk' => 'Orolayan',
'anontalk' => 'Olay para kaining IP address',
# General errors
'error' => 'Salâ',
'databaseerror' => 'Salâ sa base nin datos',
+'databaseerror-text' => 'Sarong hapot sa datos-sarayan na kasalaan an nangyari.
+Ini puwedeng minapasabot nin sarong kudol sa panuklob.',
+'databaseerror-textcl' => 'Sarong hapot sa datos-sarayan na kasalaan an nangyari.',
+'databaseerror-query' => 'Hapot: $1',
+'databaseerror-function' => 'Punksyon: $1',
+'databaseerror-error' => 'Kasalaan: $1',
'laggedslavemode' => 'Patanid: An pahina pwedeng dai nin pagbabâgo sa ngonyan.',
'readonly' => 'Nakakandado na datos-sarayan',
'enterlockreason' => 'Magkaag tabì nin rason sa pagkandado, asin ikalkulo kun nuarin bubukasón an kandado',
'rc_categories_any' => 'Dawà arín',
'rc-change-size-new' => '$1 {{PLURAL:$1|byte|bytes}} pagtatapos kan pagbabago',
'newsectionsummary' => '/* $1 */ bàgong seksyon',
-'rc-enhanced-expand' => 'Magpahiling kan mga detalye (minakaipo nin JavaScript)',
+'rc-enhanced-expand' => 'Ipahiling an mga detalye',
'rc-enhanced-hide' => 'Itago an mga detalye',
'rc-old-title' => 'orihinal na pinagmukna bilang "$1"',
Ining sityo igwang naeksperiyensiyahan na mga kakundian sa teknikal.',
'dberr-again' => 'Prubaring maghalat tabi nin nagkapirang minutos asin otrohon ikarga.',
'dberr-info' => '(Dae makakontak sa serbidor kan datos-sarayan: $1)',
+'dberr-info-hidden' => '(Dae makakontak sa serbidor kan datos-sarayan)',
'dberr-usegoogle' => 'Ika puwedeng magprubar na maghanap sa Google nguna.',
'dberr-outofdate' => 'Pasinon mo tabi na an saindang mga indekso kan satuyang laog puwedeng luwas na sa petsa.',
'dberr-cachederror' => 'Ini sarong nakasaray na kopya kan pinaghahagad na pahina, asin puwedeng bakong angat sa petsa.',
'tog-extendwatchlist' => 'Разширяване на списъка, така че да показва всички промени, не само най-скорошните',
'tog-usenewrc' => 'Групиране на последните промени и списъка за наблюдение по страници (изисква Джаваскрипт)',
'tog-numberheadings' => 'Номериране на заглавията',
-'tog-showtoolbar' => 'Ð\9fомоÑ\89на ленÑ\82а за Ñ\80едакÑ\82иÑ\80ане (изиÑ\81ква Ð\94жаваÑ\81кÑ\80ипÑ\82)',
-'tog-editondblclick' => 'РедакÑ\82иÑ\80ане пÑ\80и двойно Ñ\89Ñ\80акване (изиÑ\81ква Ð\94жаваÑ\81кÑ\80ипÑ\82)',
+'tog-showtoolbar' => 'Ð\9fоказване на инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82иÑ\82е за Ñ\80едакÑ\82иÑ\80ане',
+'tog-editondblclick' => 'РедакÑ\82иÑ\80ане на Ñ\81Ñ\82Ñ\80аниÑ\86иÑ\82е Ñ\87Ñ\80ез двойно Ñ\89Ñ\80акване',
'tog-editsection' => 'Възможност за редактиране на раздел чрез препратка [редактиране]',
-'tog-editsectiononrightclick' => 'Възможност за редактиране на раздел при щракване с десния бутон върху заглавие на раздел (изисква Джаваскрипт)',
+'tog-editsectiononrightclick' => 'Възможност за редактиране на раздел при щракване с десния бутон върху заглавието му',
'tog-showtoc' => 'Показване на съдържание (за страници с повече от три раздела)',
'tog-rememberpassword' => 'Запомяне на паролата ми в този браузър (за не повече от $1 {{PLURAL:$1|ден|дни}})',
'tog-watchcreations' => 'Добавяне на създадените от мен страници и качените от мен файлове към списъка ми за наблюдение',
'tog-shownumberswatching' => 'Показване на броя на потребителите, наблюдаващи дадена страница',
'tog-oldsig' => 'Текущ подпис:',
'tog-fancysig' => 'Без превръщане на подписа в препратка към потребителската страница',
-'tog-uselivepreview' => 'Ð\98зползване на бÑ\8aÑ\80з пÑ\80едваÑ\80иÑ\82елен пÑ\80еглед (изиÑ\81ква Ð\94жаваÑ\81кÑ\80ипÑ\82; екÑ\81пеÑ\80именÑ\82ално)',
+'tog-uselivepreview' => 'Използване на бърз предварителен преглед (експериментално)',
'tog-forceeditsummary' => 'Предупреждаване при празно поле за резюме на редакцията',
'tog-watchlisthideown' => 'Скриване на моите редакции в списъка ми за наблюдение',
'tog-watchlisthidebots' => 'Скриване на редакциите на ботове в списъка ми за наблюдение',
'tog-showhiddencats' => 'Показване на скритите категории',
'tog-norollbackdiff' => 'Пропускане на разликовата връзка след извършване на отмяна на редакции',
'tog-useeditwarning' => 'Предупреждаване при опит за напускане на страница, отворена в режим на редактиране, без да са запазени промените',
+'tog-prefershttps' => 'Да се използва винаги защитена връзка след влизане',
'underline-always' => 'Винаги',
'underline-never' => 'Никога',
'newwindow' => '(отваря се в нов прозорец)',
'cancel' => 'Отказ',
'moredotdotdot' => 'Още…',
+'morenotlisted' => 'Този списък не е пълен.',
'mypage' => 'Страница',
'mytalk' => 'Беседа',
'anontalk' => 'Беседа за адреса',
# General errors
'error' => 'Грешка',
'databaseerror' => 'Грешка при работа с базата от данни',
+'databaseerror-query' => 'Заявка: $1',
+'databaseerror-function' => 'Функция: $1',
+'databaseerror-error' => 'Грешка: $1',
'laggedslavemode' => 'Внимание: Страницата може да не съдържа последните обновявания.',
'readonly' => 'Базата от данни е затворена за промени',
'enterlockreason' => 'Посочете причина за затварянето, като дадете и приблизителна оценка кога базата от данни ще бъде отново отворена',
'changeemail-submit' => 'Промяна на е-пощата',
'changeemail-cancel' => 'Отказване',
+# Special:ResetTokens
+'resettokens-token-label' => '$1 (текуща стойност: $2)',
+
# Edit page toolbar
'bold_sample' => 'Получер текст',
'bold_tip' => 'Получер (удебелен) текст',
'compareselectedversions' => 'Сравнение на избраните версии',
'showhideselectedversions' => 'Показване/скриване на избрани версии',
'editundo' => 'връщане',
+'diff-empty' => '(Няма разлика)',
'diff-multi' => '({{PLURAL:$1|Не е показана една междинна версия|Не са показани $1 междинни версии}} от {{PLURAL:$2|един потребител|$2 потребителя}}.)',
'diff-multi-manyusers' => '({{PLURAL:$1|Не е показана една междинна версия|Не са показани $1 междинни версии}} от повече от $2 {{PLURAL:$2|потребител|потребителя}})',
'difference-missing-revision' => '{{PLURAL:$2|Не беше открита|Не бяха открити}} {{PLURAL:$2|една версия|$2 версии}} от тази разликова препратка ($1).
'prefs-dateformat' => 'Формат на датата',
'prefs-timeoffset' => 'Часово отместване',
'prefs-advancedediting' => 'Разширени настройки',
+'prefs-preview' => 'Преглед',
'prefs-advancedrc' => 'Разширени настройки',
'prefs-advancedrendering' => 'Разширени настройки',
'prefs-advancedsearchoptions' => 'Разширени настройки',
'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“',
'reuploaddesc' => 'Връщане към формуляра за качване.',
'upload-tryagain' => 'Съхраняване на промененото описание на файла',
'uploadnologin' => 'Не сте влезли',
-'uploadnologintext' => 'Ð\9dеобÑ\85одимо е да [[Special:UserLogin|влезеÑ\82е]], за да може да каÑ\87ваÑ\82е Ñ\84айлове.',
+'uploadnologintext' => 'Ð\97а да могаÑ\82 да бÑ\8aдаÑ\82 каÑ\87вани Ñ\84айлове е необÑ\85одимо $1 в Ñ\81иÑ\81Ñ\82емаÑ\82а.',
'upload_directory_missing' => 'Директорията за качване ($1) липсва и не може да бъде създадена на сървъра.',
'upload_directory_read_only' => 'Сървърът няма достъп за писане в директорията за качване „$1“.',
'uploaderror' => 'Грешка при качване',
'listfiles_size' => 'Размер',
'listfiles_description' => 'Описание',
'listfiles_count' => 'Версии',
+'listfiles-show-all' => 'Включване на старите версии на изображенията',
'listfiles-latestversion' => 'Текущата версия',
'listfiles-latestversion-yes' => 'Да',
'listfiles-latestversion-no' => 'Не',
За повече информация вижте [$2 описателната му страница].',
'sharedupload-desc-here' => 'Този файл е от $1 и може да се използва от други проекти.
Следва информация за файла, достъпна през [$2 оригиналната му описателна страница].',
+'sharedupload-desc-edit' => 'Този файл е от $1 и може да бъде използван от други проекти.
+Вероятно желаете да редактирате описанието му на [$2 неговата описателна страница].',
'filepage-nofile' => 'Не съществува файл с това име.',
'filepage-nofile-link' => 'Не съществува файл с това име, но можете [$1 да го качите].',
'uploadnewversion-linktext' => 'Качване на нова версия на файла',
'pageinfo-hidden-categories' => '{{PLURAL:$1|Скрита категория|Скрити категории}} ($1)',
'pageinfo-templates' => '{{PLURAL:$1|Включен шаблон|Включени шаблони}} ($1)',
'pageinfo-toolboxlink' => 'Информация за страницата',
+'pageinfo-redirectsto' => 'Пренасочване към',
'pageinfo-redirectsto-info' => 'инфо',
'pageinfo-contentpage-yes' => 'Да',
'pageinfo-protect-cascading' => 'Каскадни защити, започващи от тази страница',
'exif-citycreated' => 'Град, в който е направена снимката',
'exif-objectname' => 'Кратко заглавие',
'exif-specialinstructions' => 'Специални инструкции',
+'exif-headline' => 'Заглавие',
'exif-source' => 'Източник',
'exif-contact' => 'Информация за контакти',
'exif-languagecode' => 'Език',
'version-license' => 'Лиценз',
'version-poweredby-credits' => "Това уики се задвиждва от '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
'version-poweredby-others' => 'други',
+'version-poweredby-translators' => 'преводачи в translatewiki.net',
'version-credits-summary' => 'Бихме искали да изкажем признателност на следните хора за техните приноси към [[Special:Version|MediaWiki]].',
'version-license-info' => 'MediaWiki е свободен софтуер, можете да го разпространявате и/или променяте съгласно условията на GNU General Public License, както е публикуван от Free Software Foundation, версия 2 на лиценза или (по ваше усмотрение) която и да е следваща версия.
'htmlform-selectorother-other' => 'Друга',
'htmlform-no' => 'Не',
'htmlform-yes' => 'Да',
+'htmlform-chosen-placeholder' => 'Избиране',
# SQLite database support
'sqlite-has-fts' => '$1 с поддръжка на пълнотекстово търсене',
'tog-extendwatchlist' => 'Astenn ar roll evezhiañ a-benn diskouez an holl gemmoù ha neket ar re ziwezhañ hepken.',
'tog-usenewrc' => "Diskouez ar c'hemmoù nevez en ur feson kempennoc'h (rekis eo JavaScript)",
'tog-numberheadings' => 'Niverenniñ emgefre an titloù',
-'tog-showtoolbar' => 'Diskouez ar varrenn gant ar meuzioù skridaozañ',
+'tog-showtoolbar' => 'Diskouez ar varrenn ostilhoù aozañ',
'tog-editondblclick' => 'Daouglikañ evit kemmañ pajennoù',
'tog-editsection' => 'Kemmañ ur rann dre al liammoù [kemmañ]',
'tog-editsectiononrightclick' => 'Kemmañ ur rann dre glikañ a-zehou<br /> war titl ar rann',
'tog-extendwatchlist' => 'Proširi spisak praćenja za pogled svih izmjena, ne samo nedavnih',
'tog-usenewrc' => 'Grupiraj izmjene po stranicama sa nedavnih izmjena i praćenih članaka',
'tog-numberheadings' => 'Automatski numeriši podnaslove',
-'tog-showtoolbar' => 'Prikaži dugmiće za izmjene (JavaScript)',
+'tog-showtoolbar' => 'Prikaži traku s alatkama za uređivanje',
'tog-editondblclick' => 'Izmijeni stranice dvostrukim klikom',
'tog-editsection' => 'Omogući da mijenjam pojedinačne odjeljke putem [uredi] linka',
'tog-editsectiononrightclick' => 'Uključite uređivanje odjeljka sa pritiskom na desno dugme miša u naslovu odjeljka',
'newwindow' => '(otvara se u novom prozoru)',
'cancel' => 'Poništite',
'moredotdotdot' => 'Još...',
-'morenotlisted' => 'Više nije prikazano...',
+'morenotlisted' => 'Ovaj spisak nije kompletan.',
'mypage' => 'Korisnička stranica',
'mytalk' => 'Razgovor',
'anontalk' => 'Razgovor za ovu IP adresu',
'upload_source_file' => ' (datoteka na Vašem računaru)',
# Special:ListFiles
-'listfiles-summary' => 'Ova posebna stranica prikazuje sve postavljene datoteke.
-Kada je filtrirana od strane korisnika, prikazane su samo datoteke ako je korisnik postavio posljednju verziju te datoteke.',
+'listfiles-summary' => 'Ova posebna stranica prikazuje sve postavljene datoteke.',
'listfiles_search_for' => 'Traži medije po imenu:',
'imgfile' => 'datoteka',
'listfiles' => 'Spisak slika',
'changeemail-submit' => 'Canvia de correu electrònic',
'changeemail-cancel' => 'Cancel·la',
+# Special:ResetTokens
+'resettokens' => 'Reinicia els testimonis',
+'resettokens-no-tokens' => 'No hi ha testimonis per reiniciar.',
+'resettokens-legend' => 'Reinicia els testimonis',
+'resettokens-tokens' => 'Testimonis:',
+'resettokens-token-label' => '$1 (valor actual: $2)',
+'resettokens-watchlist-token' => 'Testimoni del canal web (Atom/RSS) dels [[Special:Watchlist|canvis a la llista de seguiment]]',
+'resettokens-done' => "S'han reiniciat els testimonis.",
+'resettokens-resetbutton' => 'Reinicia els testimonis seleccionats',
+
# Edit page toolbar
'bold_sample' => 'Text en negreta',
'bold_tip' => 'Text en negreta',
'right-editusercssjs' => "Editar els fitxers de configuració CSS i JS d'altres usuaris",
'right-editusercss' => "Editar els fitxers de configuració CSS d'altres usuaris",
'right-edituserjs' => "Editar els fitxers de configuració JS d'altres usuaris",
+'right-viewmywatchlist' => 'Mostra la llista de seguiment pròpia',
+'right-editmyoptions' => 'Edita les pròpies preferències',
'right-rollback' => "Revertir ràpidament l'últim editor d'una pàgina particular",
'right-markbotedits' => 'Marcar les reversions com a edicions de bot',
'right-noratelimit' => "No veure's afectat pels límits d'accions",
'action-userrights-interwiki' => "modificar permisos d'usuari en altres wikis",
'action-siteadmin' => 'bloquejar o desbloquejar la base de dades',
'action-sendemail' => 'enviar missatges de correu',
+'action-editmywatchlist' => 'edita la llista de seguiment',
+'action-viewmywatchlist' => 'mostra la llista de seguiment',
+'action-viewmyprivateinfo' => 'mostra la informació personal',
+'action-editmyprivateinfo' => 'edita la informació personal',
# Recent changes
'nchanges' => '$1 {{PLURAL:$1|canvi|canvis}}',
'listfiles_size' => 'Mida (octets)',
'listfiles_description' => 'Descripció',
'listfiles_count' => 'Versions',
+'listfiles-show-all' => 'Inclou versions antigues de les imatges',
'listfiles-latestversion' => 'Versió actual',
'listfiles-latestversion-yes' => 'Sí',
'randomincategory' => 'Pàgina aleatòria en la categoria',
'randomincategory-invalidcategory' => '«$1» no és un nom de categoria vàlid.',
'randomincategory-nopages' => 'No hi ha pàgines a la categoria [[:Category:$1|$1]].',
+'randomincategory-selectcategory' => "Obté una pàgina a l'atzar de la categoria: $1 $2.",
+'randomincategory-selectcategory-submit' => 'Vés-hi',
# Random redirect
'randomredirect' => "Redirecció a l'atzar",
'thumbnail-more' => 'Amplia',
'filemissing' => 'Fitxer inexistent',
'thumbnail_error' => "S'ha produït un error en crear la miniatura: $1",
+'thumbnail_error_remote' => "Missatge d'error de $1:
+$2",
'djvu_page_error' => "La pàgina DjVu està fora de l'abast",
'djvu_no_xml' => "No s'ha pogut recollir l'XML per al fitxer DjVu",
'thumbnail-temp-create' => "No s'ha pogut creat el fitxer de miniatura temporal",
'version-entrypoints-header-url' => 'URL',
# Special:Redirect
+'redirect' => 'Redirigeix per fitxer, usuari o ID de la revisió',
+'redirect-legend' => 'Redirigeix a un fitxer o a una pàgina',
'redirect-submit' => 'Vés-hi',
+'redirect-lookup' => 'Consulta:',
'redirect-value' => 'Valor:',
'redirect-user' => "ID d'usuari",
+'redirect-revision' => 'Revisió de la pàgina',
+'redirect-file' => 'Nom del fitxer',
'redirect-not-exists' => "No s'ha trobat el valor",
# Special:FileDuplicateSearch
'tags' => 'Etiquetes de canvi vàlides',
'tag-filter' => "Filtre d'[[Special:Tags|etiquetes]]:",
'tag-filter-submit' => 'Filtra',
+'tag-list-wrapper' => '([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetes}}]]: $2)',
'tags-title' => 'Etiquetes',
'tags-intro' => 'Aquesta pàgina llista les etiquetes amb les què el programari pot marcar una modificació, i llur significat.',
'tags-tag' => "Nom de l'etiqueta",
'dberr-problems' => 'Ho sentim. Aquest lloc web està experimentant dificultats tècniques.',
'dberr-again' => 'Intenteu esperar uns minuts i tornar a carregar.',
'dberr-info' => '(No es pot contactar amb el servidor de dades: $1)',
+'dberr-info-hidden' => '(No es pot contactar amb el servidor de la base de dades)',
'dberr-usegoogle' => 'Podeu intentar fer la cerca via Google mentrestant.',
'dberr-outofdate' => 'Tingueu en compte que la seva indexació del nostre contingut pot no estar actualitzada.',
'dberr-cachederror' => 'A continuació hi ha una còpia emmagatzemada de la pàgina demanada, que pot no estar actualitzada.',
# Edit page toolbar
'bold_sample' => 'Дерстино до йоза',
'bold_tip' => 'Дерстино до йоза',
-'italic_sample' => 'Ð\9aÑ\83Ñ\80Ñ\81еттан до йоза',
-'italic_tip' => 'Ð\9aÑ\83Ñ\80Ñ\81еттан до йоза',
+'italic_sample' => 'Сеттан до йоза',
+'italic_tip' => 'Сеттан до йоза',
'link_sample' => 'Хьажориган коьрта могlа',
'link_tip' => 'Чоьхьа хьажориг',
'extlink_sample' => 'http://www.example.com хьажориг корта',
لەیادت بێت لەوانەیە پێرستەکانیان بۆ گەڕانی ناو {{SITENAME}}، کاتبەسەرچوو بێت.',
# Preferences page
-'preferences' => 'ھەڵبەژاردەکان',
+'preferences' => 'ھەڵبژاردەکان',
'mypreferences' => 'ھەڵبژاردەکان',
'prefs-edits' => 'ژمارەی گۆڕانکارییەکان:',
'prefsnologin' => 'لەژوورەوە نیت',
'minutes-abbrev' => '$1خ',
'hours-abbrev' => '$1ک',
'days-abbrev' => '$1ڕ',
-'seconds' => '{{PLURAL:$1|$1 چرکە|$1 چرکە}}',
-'minutes' => '{{PLURAL:$1|$1 خولەک|$1 خولەک}}',
-'hours' => '{{PLURAL:$1|$1 کاتژمێر|$1 کاتژمێر}}',
-'days' => '{{PLURAL:$1|$1 ڕۆژ|$1 ڕۆژ}}',
-'ago' => '$1 پێش',
+'seconds' => '{{PLURAL:$1|$1 چرکە}}',
+'minutes' => '{{PLURAL:$1|$1 خولەک}}',
+'hours' => '{{PLURAL:$1|$1 کاتژمێر}}',
+'days' => '{{PLURAL:$1|$1 ڕۆژ}}',
+'weeks' => '{{PLURAL:$1|$1 حەفتە}}',
+'months' => '{{PLURAL:$1|$1 مانگ}}',
+'years' => '{{PLURAL: $1|$1 ساڵ}}',
+'ago' => '$1 لەمە پێش',
'just-now' => 'ھەرئێستا',
+# Human-readable timestamps
+'hours-ago' => '$1 {{PLURAL:$1|کاتژمێر}} لەمه پێش',
+'minutes-ago' => '$1 {{PLURAL:$1|خولەک}} لەمە پێش',
+'seconds-ago' => '$1 {{PLURAL:$1|چرکە}} لەمە پێش',
+'monday-at' => 'دووشەممە $1',
+'tuesday-at' => 'سێشەممە $1',
+'wednesday-at' => 'چوارشەممە $1',
+'thursday-at' => 'پێنجشەممە $1',
+'friday-at' => 'ھەینی $1',
+'saturday-at' => 'شەممە $1',
+'sunday-at' => 'یەکشەممە $1',
+'yesterday-at' => 'دوێنێ $1',
+
# Bad image list
'bad_image_list' => 'فۆرمات بەم شێوەی خوارەوەیە:
'pageinfo-redirects-name' => 'Počet přesměrování na tuto stránku',
'pageinfo-subpages-name' => 'Podstránky této stránky',
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|přesměrování}}; $3 {{PLURAL:$3|nepřesměrování}})',
-'pageinfo-firstuser' => 'Zakladatel stránky',
+'pageinfo-firstuser' => 'Stránku vytvořil',
'pageinfo-firsttime' => 'Datum založení stránky',
-'pageinfo-lastuser' => 'Nejnovější editor',
-'pageinfo-lasttime' => 'Datum nejnovější editace',
+'pageinfo-lastuser' => 'Naposledy editoval',
+'pageinfo-lasttime' => 'Datum poslední editace',
'pageinfo-edits' => 'Celkový počet editací',
'pageinfo-authors' => 'Celkový počet různých autorů',
'pageinfo-recent-edits' => 'Počet nedávných ($1) editací',
'rc-change-size' => '$1 {{PLURAL:$1|Byte|Bytes}}',
'rc-change-size-new' => '$1 {{PLURAL:$1|byte|bytes}} efter ændring',
'newsectionsummary' => '/* $1 */ nyt afsnit',
-'rc-enhanced-expand' => 'Vis detaljer (kræver JavaScript)',
+'rc-enhanced-expand' => 'Vis detaljer',
'rc-enhanced-hide' => 'Skjul detaljer',
'rc-old-title' => 'oprindeligt oprettet som "$1"',
'revisionyear' => array( 1, 'REVISIONYEAR' ),
'revisiontimestamp' => array( 1, 'REVISIONTIMESTAMP' ),
'revisionuser' => array( 1, 'REVISIONUSER' ),
+ 'revisionsize' => array( 1, 'REVISIONSIZE' ),
'plural' => array( 0, 'PLURAL:' ),
'fullurl' => array( 0, 'FULLURL:' ),
'fullurle' => array( 0, 'FULLURLE:' ),
* Intended blockee: $7
You can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.
-You cannot use the 'email this user' feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.
+You cannot use the \"email this user\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.
Your current IP address is $3, and the block ID is #$5.
Please include all above details in any queries you make.",
-'autoblockedtext' => 'Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.
+'autoblockedtext' => "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.
The reason given is:
-:\'\'$2\'\'
+:''$2''
* Start of block: $8
* Expiry of block: $6
You may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.
-Note that you may not use the "email this user" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.
+Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.
Your current IP address is $3, and the block ID is #$5.
-Please include all above details in any queries you make.',
+Please include all above details in any queries you make.",
'blockednoreason' => 'no reason given',
'whitelistedittext' => 'You have to $1 to edit pages.',
'confirmedittext' => 'You must confirm your email address before editing pages.
To include a file in a page, use a link in one of the following forms:
* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' to use the full version of the file
-* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code>''' to use a 200 pixel wide rendition in a box in the left margin with 'alt text' as description
+* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code>''' to use a 200 pixel wide rendition in a box in the left margin with \"alt text\" as description
* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' for directly linking to the file without displaying the file",
'upload-permitted' => 'Permitted file types: $1.',
'upload-preferred' => 'Preferred file types: $1.',
'upload_source_file' => '(a file on your computer)',
# Special:ListFiles
-'listfiles-summary' => 'This special page shows all uploaded files.',
-'listfiles_search_for' => 'Search for media name:',
-'imgfile' => 'file',
-'listfiles' => 'File list',
-'listfiles_thumb' => 'Thumbnail',
-'listfiles_date' => 'Date',
-'listfiles_name' => 'Name',
-'listfiles_user' => 'User',
-'listfiles_size' => 'Size',
-'listfiles_description' => 'Description',
-'listfiles_count' => 'Versions',
-'listfiles-show-all' => 'Include old versions of images',
-'listfiles-latestversion' => 'Current version',
+'listfiles-summary' => 'This special page shows all uploaded files.',
+'listfiles_search_for' => 'Search for media name:',
+'imgfile' => 'file',
+'listfiles' => 'File list',
+'listfiles_thumb' => 'Thumbnail',
+'listfiles_date' => 'Date',
+'listfiles_name' => 'Name',
+'listfiles_user' => 'User',
+'listfiles_size' => 'Size',
+'listfiles_description' => 'Description',
+'listfiles_count' => 'Versions',
+'listfiles-show-all' => 'Include old versions of images',
+'listfiles-latestversion' => 'Current version',
'listfiles-latestversion-yes' => 'Yes',
-'listfiles-latestversion-no' => 'No',
+'listfiles-latestversion-no' => 'No',
# File description page
'file-anchor-link' => 'File',
'watchmethod-recent' => 'checking recent edits for watched pages',
'watchmethod-list' => 'checking watched pages for recent edits',
'watchlistcontains' => 'Your watchlist contains $1 {{PLURAL:$1|page|pages}}.',
-'iteminvalidname' => "Problem with item '$1', invalid name...",
+'iteminvalidname' => 'Problem with item "$1", invalid name...',
'wlnote' => "Below {{PLURAL:$1|is the last change|are the last '''$1''' changes}} in the last {{PLURAL:$2|hour|'''$2''' hours}}, as of $3, $4.",
'wlshowlast' => 'Show last $1 hours $2 days $3',
'watchlist-options' => 'Watchlist options',
# Special:ChangeEmail
'changeemail' => 'Cambiar la dirección de correo electrónico',
-'changeemail-header' => 'Cambiar la dirección de correo electrónico de la cuenta',
+'changeemail-header' => 'Cambiar la dirección de correo de la cuenta',
'changeemail-text' => 'Rellena este formulario para cambiar tu dirección de correo electrónico. Debes introducir la contraseña para confirmar este cambio.',
'changeemail-no-info' => 'Debes iniciar sesión para acceder directamente a esta página.',
'changeemail-oldemail' => 'Dirección de correo electrónico actual:',
'shortpages' => 'Lühikesed leheküljed',
'longpages' => 'Pikad leheküljed',
'deadendpages' => 'Edasipääsuta leheküljed',
-'deadendpagestext' => 'Järgmised leheküljed ei viita ühelegi teisele viki leheküljele.',
+'deadendpagestext' => 'Järgmised leheküljed ei viita ühelegi teisele {{GRAMMAR:genitive|{{SITENAME}}}} leheküljele.',
'protectedpages' => 'Kaitstud leheküljed',
'protectedpages-indef' => 'Ainult määramata ajani kaitstud',
'protectedpages-cascade' => 'Ainult kaskaadkaitsega',
'filerevert-legend' => 'Tiedoston palautus',
'filerevert-intro' => '<span class="plainlinks">Olet palauttamassa tiedostoa \'\'\'[[Media:$1|$1]]\'\'\' [$4 versioon, joka luotiin $2 kello $3].</span>',
'filerevert-comment' => 'Syy',
-'filerevert-defaultcomment' => 'Palautettiin versioon, joka luotiin $1 kello $2',
+'filerevert-defaultcomment' => 'Palautettiin versioon, joka luotiin $1 kello $2 (UTC)',
'filerevert-submit' => 'Palauta',
'filerevert-success' => '<span class="plainlinks">\'\'\'[[Media:$1|$1]]\'\'\' on palautettu [$4 versioon, joka luotiin $2 kello $3].</span>',
'filerevert-badversion' => 'Tiedostosta ei ole luotu versiota kyseisellä ajan hetkellä.',
'limitreport-walltime' => 'Oikea ajankäyttö',
'limitreport-walltime-value' => '$1 {{PLURAL:$1|sekunti|sekuntia}}',
'limitreport-postexpandincludesize-value' => '$1/$2 tavua',
-'limitreport-templateargumentsize' => 'Mallin argumenttikoko',
+'limitreport-templateargumentsize' => 'Mallineen argumenttien koko',
'limitreport-templateargumentsize-value' => '$1/$2 tavua',
'limitreport-expansiondepth' => 'Korkein laajennussyvyys',
'morenotlisted' => 'רשימה זו אינה מלאה.',
'mypage' => 'דף משתמש',
'mytalk' => 'שיחה',
-'anontalk' => '×\94ש×\99×\97×\94 ×¢×\91×\95ר IP ×\96×\94',
+'anontalk' => '×\93×£ ×\94ש×\99×\97×\94 ×¢×\91×\95ר ×\9bת×\95×\91ת IP ×\96×\95',
'navigation' => 'ניווט',
'and' => ' וגם',
'linkstoimage-more' => 'יותר {{PLURAL:$1|מדף אחד מקשר|מ־$1 דפים מקשרים}} לקובץ זה.
הרשימה הבאה מראה רק את {{PLURAL:$1|הדף הראשון שמקשר|$1 הדפים הראשונים שמקשרים}} לקובץ זה.
ניתן לצפות ב[[Special:WhatLinksHere/$2|רשימה המלאה]].',
-'nolinkstoimage' => '×\90×\99×\9f ×\93פ×\99×\9d שמשתמשים בקובץ זה.',
+'nolinkstoimage' => '×\90×\99×\9f ×\93פ×\99×\9d ×\94משתמשים בקובץ זה.',
'morelinkstoimage' => 'ראו [[Special:WhatLinksHere/$1|דפים נוספים]] שמשתמשים בקובץ זה.',
'linkstoimage-redirect' => '$1 (הפניה של קובץ) $2',
'duplicatesoffile' => '{{PLURAL:$1|הקובץ הבא זהה|הקבצים הבאים זהים}} לקובץ זה ([[Special:FileDuplicateSearch/$2|לפרטים נוספים]]):',
'deletepage' => 'מחיקה',
'confirm' => 'אישור',
'excontent' => 'תוכן היה: "$1"',
-'excontentauthor' => "התוכן היה: '$1' וה{{gender:$2|תורם היחיד היה|תורמת היחידה הייתה}} [[Special:Contributions/$2|$2]] ([[User Talk:$2|ש]])",
+'excontentauthor' => 'התוכן היה: "$1" ({{gender:$2|והתורם היחיד היה|והתורמת היחידה הייתה}} [[Special:Contributions/$2|$2]])',
'exbeforeblank' => 'תוכן לפני שרוקן היה: "$1"',
'exblank' => 'הדף היה ריק',
'delete-confirm' => 'מחיקת $1',
'protectlogtext' => 'להלן רשימה של שינויי ההגנה על דפים.
ראו גם את [[Special:ProtectedPages|רשימת הדפים המוגנים]] הנוכחית.',
'protectedarticle' => 'הפעיל הגנה על [[$1]]',
-'modifiedarticleprotection' => 'ש×\99× ×\94 ×\90ת ר×\9eת ×\94×\94×\92× ×\94 ש×\9c [[$1]]',
+'modifiedarticleprotection' => 'ש×\99× ×\94 ×\90ת ×\94×\92×\93ר×\95ת ×\94×\94×\92× ×\94 ש×\9c "[[$1]]"',
'unprotectedarticle' => 'ביטל את ההגנה על [[$1]]',
'movedarticleprotection' => 'העביר את הגדרות ההגנה מ"[[$2]]" ל"[[$1]]"',
'protect-title' => 'שינוי רמת ההגנה של "$1"',
'ipbenableautoblock' => 'חסימה אוטומטית גם של כתובת ה־IP האחרונה שהשתמש בה ושל כל כתובת IP שינסה להשתמש בה בעתיד',
'ipbsubmit' => 'חסימה',
'ipbother' => 'זמן אחר:',
-'ipboptions' => 'שעת×\99×\99×\9d:2 hours,×\99×\95×\9d:1 day,ש×\9c×\95ש×\94 ×\99×\9e×\99×\9d:3 days,ש×\91×\95×¢:1 week,ש×\91×\95×¢×\99×\99×\9d:2 weeks,×\97×\95×\93ש:1 month,ש×\9c×\95ש×\94 ×\97×\95×\93ש×\99×\9d:3 months,ש×\99ש×\94 ×\97×\95×\93ש×\99×\9d:6 months,×©× ×\94:1 year,×\9c×\96×\9e×\9f ×\91×\9cת×\99 ×\9e×\95×\92×\91×\9c:infinite',
+'ipboptions' => 'שעתיים:2 hours,יום:1 day,שלושה ימים:3 days,שבוע:1 week,שבועיים:2 weeks,חודש:1 month,שלושה חודשים:3 months,שישה חודשים:6 months,שנה:1 year,זמן בלתי מוגבל:infinite',
'ipbotheroption' => 'אחר',
'ipbotherreason' => 'סיבה אחרת/נוספת:',
'ipbhidename' => 'הסתרת שם המשתמש מהעריכות ומהרשימות',
-'ipbwatchuser' => 'מעקב אחרי דפי המשתמש והשיחה של משתמש זה',
+'ipbwatchuser' => 'מעקב אחר דף המשתמש ודף השיחה של משתמש זה',
'ipb-disableusertalk' => 'ביטול האפשרות של המשתמש לערוך את דף השיחה של עצמו בעת החסימה',
'ipb-change-block' => 'חסימת המשתמש מחדש עם הגדרות אלה',
'ipb-confirm' => 'אישור החסימה',
'blocklogpage' => 'יומן חסימות',
'blocklog-showlog' => 'משתמש זה נחסם בעבר. יומן החסימות מוצג למטה:',
'blocklog-showsuppresslog' => 'משתמש זה נחסם והוסתר בעבר. יומן ההסתרות מוצג למטה:',
-'blocklogentry' => '{{GENDER:$4|חסם|חסמה}} את [[$1]] למשך $2 $3',
+'blocklogentry' => 'חסם את [[$1]] למשך $2 $3',
'reblock-logentry' => 'שינה את הגדרות החסימה של [[$1]] עם זמן פקיעה של $2 $3',
'blocklogtext' => 'זהו יומן פעולות החסימה והשחרור של משתמשים.
כתובות IP שנחסמו אוטומטית אינן מופיעות.
'cant-move-user-page' => 'אינכם מורשים להעביר דפי משתמש (למעט דפי משנה).',
'cant-move-to-user-page' => 'אינכם מורשים להעביר דף לדף משתמש (למעט לדף משנה של דף משתמש).',
'newtitle' => 'לשם החדש:',
-'move-watch' => 'מעקב אחרי דף המקור ואחרי דף היעד',
+'move-watch' => 'מעקב אחר דף המקור ואחר דף היעד',
'movepagebtn' => 'העברה',
'pagemovedsub' => 'ההעברה הושלמה בהצלחה',
'movepage-moved' => 'הדף "$1" הועבר לשם "$2".',
'logentry-delete-delete' => '$1 {{GENDER:$2|מחק|מחקה}} את הדף $3',
'logentry-delete-restore' => '$1 {{GENDER:$2|שחזר|שחזרה}} את הדף $3',
'logentry-delete-event' => '$1 {{GENDER:$2|שינה|שינתה}} את מצב התצוגה של {{PLURAL:$5|פעולת יומן|$5 פעולות יומן}} של $3: $4',
-'logentry-delete-revision' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c {{PLURAL:$5|×\92רס×\94|$5 ×\92רס×\90×\95ת}} ש×\9c ×\94דף $3: $4',
+'logentry-delete-revision' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c {{PLURAL:$5|×\92רס×\94|$5 ×\92רס×\90×\95ת}} ×\91דף $3: $4',
'logentry-delete-event-legacy' => '$1 {{GENDER:$2|שינה|שינתה}} את מצב התצוגה של פעולות יומן של $3',
'logentry-delete-revision-legacy' => '$1 {{GENDER:$2|שינה|שינתה}} את מצב התצוגה של גרסאות בדף $3',
'logentry-suppress-delete' => '$1 {{GENDER:$2|הסתיר|הסתירה}} לחלוטין את הדף $3',
'logentry-suppress-event' => '$1 {{GENDER:$2|שינה|שינתה}} בסודיות את מצב התצוגה של {{PLURAL:$5|פעולת יומן|$5 פעולות יומן}} של $3: $4',
-'logentry-suppress-revision' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\91ס×\95×\93×\99×\95ת ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c {{PLURAL:$5|×\92רס×\94|$5 ×\92רס×\90×\95ת}} ש×\9c ×\94דף $3: $4',
+'logentry-suppress-revision' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\91ס×\95×\93×\99×\95ת ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c {{PLURAL:$5|×\92רס×\94|$5 ×\92רס×\90×\95ת}} ×\91דף $3: $4',
'logentry-suppress-event-legacy' => '$1 {{GENDER:$2|שינה|שינתה}} בסודיות את מצב התצוגה של פעולות יומן של $3',
-'logentry-suppress-revision-legacy' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\91ס×\95×\93×\99×\95ת ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c ×\92רס×\90×\95ת ש×\9c ×\94דף $3',
+'logentry-suppress-revision-legacy' => '$1 {{GENDER:$2|ש×\99× ×\94|ש×\99× ×ª×\94}} ×\91ס×\95×\93×\99×\95ת ×\90ת ×\9eצ×\91 ×\94תצ×\95×\92×\94 ש×\9c ×\92רס×\90×\95ת ×\91דף $3',
'revdelete-content-hid' => 'התוכן הוסתר',
'revdelete-summary-hid' => 'תקציר העריכה הוסתר',
'revdelete-uname-hid' => 'שם המשתמש הוסתר',
'revdelete-uname-unhid' => 'הסתרת שם המשתמש בוטלה',
'revdelete-restricted' => 'נוספו הגבלות למפעילי מערכת',
'revdelete-unrestricted' => 'הוסרו הגבלות ממפעילי מערכת',
-'logentry-move-move' => '$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 ל$4',
+'logentry-move-move' => '$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 ל{{GRAMMAR:תחילית|$4}}',
'logentry-move-move-noredirect' => '$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 ל{{GRAMMAR:תחילית|$4}} בלי להשאיר הפניה',
'logentry-move-move_redir' => '$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 ל{{GRAMMAR:תחילית|$4}} תוך דריסת הפניה',
'logentry-move-move_redir-noredirect' => '$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 ל{{GRAMMAR:תחילית|$4}} תוך דריסת הפניה ובלי להשאיר הפניה',
'api-error-invalid-file-key' => 'שגיאה פנימית: הקובץ לא נמצא במאגר הזמני.',
'api-error-missingparam' => 'שגיאה פנימית: פרמטרים חסרים בבקשה שנשלחה.',
'api-error-missingresult' => 'שגיאה פנימית: לא ניתן לקבוע אם ההעתקה הצליחה.',
-'api-error-mustbeloggedin' => '×¢×\9c×\99×\9b×\9d ×\9c×\94×\99×\95ת ×\9e×\97×\95×\91ר×\99×\9d לחשבון כדי להעלות קבצים.',
+'api-error-mustbeloggedin' => '×\99ש ×\9c×\94×\99×\9b× ×¡ לחשבון כדי להעלות קבצים.',
'api-error-mustbeposted' => 'שגיאה פנימית: הבקשה דורשת שימוש בשיטת POST של HTTP.',
'api-error-noimageinfo' => 'ההעלאה הושלמה בהצלחה, אבל השרת לא נתן לנו שום מידע על הקובץ.',
'api-error-nomodule' => 'שגיאה פנימית: מודול ההעלאה אינו מוגדר.',
'compareselectedversions' => 'Kiválasztott változatok összehasonlítása',
'showhideselectedversions' => 'Kiválasztott változatok láthatóságának beállítása',
'editundo' => 'visszavonás',
+'diff-empty' => '(Nincs különbség)',
'diff-multi' => '({{PLURAL:$2|egy|$2}} szerkesztő {{PLURAL:$1|egy|$1}} közbeeső változata nincs mutatva)',
'diff-multi-manyusers' => '({{PLURAL:$1|Egy közbeeső változat|$1 közbeeső változat}} nincs mutatva, amit $2 szerkesztő módosított)',
'difference-missing-revision' => 'A(z) "{{PAGENAME}}" nevű oldal #$1 $2 változata nem létezik.
'recentchanges' => 'Friss változtatások',
'recentchanges-legend' => 'A friss változtatások beállításai',
'recentchanges-summary' => 'Ezen a lapon a wikiben történt legutóbbi fejleményeket lehet nyomon követni.',
+'recentchanges-noresult' => 'A megadott időszakban nincs a feltételeknek megfelelő szerkesztés.',
'recentchanges-feed-description' => 'Kövesd a wiki friss változtatásait ezzel a hírcsatornával.',
'recentchanges-label-newpage' => 'Ezzel a szerkesztéssel egy új lap jött létre',
'recentchanges-label-minor' => 'Ez egy apró szerkesztés',
'sp-contributions-logs' => 'log',
'sp-contributions-talk' => 'bicara',
'sp-contributions-userrights' => 'pengelolaan hak pengguna',
-'sp-contributions-blocked-notice' => 'Pengguna ini sedang di blok. log pemblokiran terakhir ditampilkan berikut untuk referensi:',
+'sp-contributions-blocked-notice' => 'Pengguna ini sedang diblok. Log pemblokiran terakhir ditampilkan berikut untuk referensi:',
'sp-contributions-blocked-notice-anon' => 'Alamat IP ini diblokir pada saat ini.
Catatan log pemblokiran terakhir tersedia di bawah ini sebagai rujukan:',
'sp-contributions-search' => 'Cari kontribusi',
'enotif_body_intro_changed' => '{{SITENAME}}のページ「$1」が$PAGEEDITDATEに、$2 によって{{GENDER:$2|変更}}されました。現在の版は $3 で閲覧できます。',
'enotif_lastvisited' => '最終訪問以降のすべての変更は $1 をご覧ください。',
'enotif_lastdiff' => 'この変更内容を表示するには $1 をご覧ください。',
-'enotif_anon_editor' => '匿名利用者「$1」',
+'enotif_anon_editor' => '匿名利用者 $1',
'enotif_body' => '$WATCHINGUSERNAMEさん
$PAGEINTRO $NEWPAGE
'badarticleerror' => 'Haec actio non perfici potest in hac pagina.',
'cannotdelete' => 'Pagina vel fasciculus "$1" deleri non potuit.
Fortasse usor alius iam deleverat.',
-'cannotdelete-title' => 'Paginam "$1" delere non contigit.',
+'cannotdelete-title' => 'Paginam "$1" delere non contigit',
'badtitle' => 'Titulus malus',
'badtitletext' => 'Nomen paginae quaestae fuit invalidum, vacuum, aut praeverbium interlingualem vel intervicialem habuit. Fortasse insunt una aut plus litterarum quae in titulis non possunt inscribier.',
'wrong_wfQuery_params' => 'Parametri incorrectae pro wfQuery()<br />
# Revision feed
'history-feed-title' => 'Historia',
-'history-feed-description' => 'Conspectus recensionum huius paginae',
+'history-feed-description' => 'Historia emendationum huius paginae',
'history-feed-item-nocomment' => '$1 ad $2',
# Revision deletion
'revdel-restore-visible' => 'Recensiones visibiles',
'pagehist' => 'Historia paginae',
'deletedhist' => 'Historia deleta',
-'revdelete-otherreason' => 'Aliae/plures causae:',
+'revdelete-otherreason' => 'Causa alia vel explicatio:',
'revdelete-reasonotherlist' => 'Causa alia',
'revdelete-edit-reasonlist' => 'Causas deletionum recensere',
'revdelete-offender' => 'Auctor emendationis:',
'prefs-signature' => 'Subscriptio',
'prefs-preview' => 'Praevisum',
'prefs-advancedwatchlist' => 'Praeferentiae monstrare',
-'prefs-displayrc' => 'Praeferentiae monstrare',
-'prefs-displaysearchoptions' => 'Praeferentiae monstrare',
-'prefs-displaywatchlist' => 'Praeferentiae monstrare',
+'prefs-displayrc' => 'Praeferentiae vultus',
+'prefs-displaysearchoptions' => 'Praeferentiae vultus',
+'prefs-displaywatchlist' => 'Praeferentiae vultus',
'prefs-diffs' => 'Differentiae',
# User rights
# User preference toggles
'tog-underline' => 'Linken ënnersträichen:',
'tog-justify' => "Ränner vum Text riichten (''justify'')",
-'tog-hideminor' => 'Kleng Ännerungen an de rezenten Ännerungen verstoppen',
+'tog-hideminor' => 'Kleng Ännerungen an de rezenten Ännerunge verstoppen',
'tog-hidepatrolled' => 'Iwwerkuckten Ännerungen an de "Rezenten Ännerungen" verstoppen',
'tog-newpageshidepatrolled' => 'Iwwerkuckte Säiten op der Lëscht vun den "Neie Säite" verstoppen',
'tog-extendwatchlist' => 'Iwwerwaachungslëscht op all Ännerungen ausbreeden, net nëmmen op déi rezentst',
Wann dat net de Fall ass, hutt Dir eventuell e Feeler an der Software fonnt.
Mellt dëst w.e.g. bei engem [[Special:ListUsers/sysop|Administrateur]] a vergiesst net d'URL unzeginn.",
'missingarticle-rev' => '(Versiounsnummer: $1)',
-'missingarticle-diff' => '(Ënnerscheed tëschent Versiounen: $1, $2)',
+'missingarticle-diff' => '(Ënnerscheed tëscht Versiounen: $1, $2)',
'readonly_lag' => "D'Datebank gouf automatesch gespaart fir datt d'Zweetserveren (slaves) nees mat dem Haaptserver (master) synchron geschalt kënne ginn.",
'internalerror' => 'Interne Feeler',
'internalerror_info' => 'Interne Feeler: $1',
'loginsuccesstitle' => 'Umeldung huet geklappt',
'loginsuccess' => "'''Dir sidd elo als \"\$1\" op {{SITENAME}} ugemellt.'''",
'nosuchuser' => 'Et gëtt kee Benotzernumm mam Numm "$1".
-Beim Benotzernumm gëtt tëschent groussen a klenge Buschtawen ënnerscheet (casesensitive).
+Beim Benotzernumm gëtt tëscht groussen a klenge Buschtawen ënnerscheet (casesensitive).
Kuckt w.e.g. op d\'Schreifweis richteg ass, oder [[Special:UserLogin/signup|maacht en neie Benotzerkont op]].',
'nosuchusershort' => 'De Benotzernumm "$1" gëtt et net.
Kuckt w.e.g. op d\'Schreifweis richteg ass.',
'nocreatetext' => "Op {{SITENAME}} gouf d'Schafe vun neie Säite limitéiert. Dir kënnt Säiten déi scho bestinn änneren oder Iech [[Special:UserLogin|umellen]].",
'nocreate-loggedin' => 'Dir hutt keng Berechtigung fir nei Säiten unzeleeën.',
'sectioneditnotsupported-title' => 'Ännere vum Abschnitt gëtt net ënnerstëtzt',
-'sectioneditnotsupported-text' => "D'Ännere vun Abschnitten gëtt op dëser Ännerungssäit net ënnerstetzt.",
+'sectioneditnotsupported-text' => "D'Ännere vun Abschnitte gëtt op dëser Ännerungssäit net ënnerstëtzt.",
'permissionserrors' => 'Net genuch Rechter',
'permissionserrorstext' => 'Dir hutt net genuch Rechter fir déi Aktioun auszeféieren. {{PLURAL:$1|Grond|Grënn}}:',
'permissionserrorstext-withaction' => 'Dir sidd, aus {{PLURAL:$1|dësem Grond|dëse Grënn}}, net berechtegt $2 :',
# Diffs
'history-title' => '$1: Historique vun de Versiounen',
-'difference-title' => '$1: Ënnerscheed tëschent de Versiounen',
-'difference-title-multipage' => '$1 a(n) $2: Ënnerscheed tëschent de Säiten',
-'difference-multipage' => '(Ënnerscheed tëschent Säiten)',
+'difference-title' => '$1: Ënnerscheed tëscht de Versiounen',
+'difference-title-multipage' => '$1 a(n) $2: Ënnerscheed tëscht de Säiten',
+'difference-multipage' => '(Ënnerscheed tëscht Säiten)',
'lineno' => 'Linn $1:',
'compareselectedversions' => 'Ausgewielte Versioune vergläichen',
'showhideselectedversions' => 'Erausgesicht Versioune weisen/verstoppen',
'right-deletelogentry' => 'Eenzel Androungen an de Logbicher läschen a restauréieren',
'right-deleterevision' => 'Spezifesch Versioune vu Säite läschen a restauréieren',
'right-deletedhistory' => 'Weis geläscht Versiounen am Historique, ouni den associéierten Text',
-'right-deletedtext' => "Geläschten Text an d'Ännerungen tëschent de geläschte Versioune weisen",
+'right-deletedtext' => "Geläschten Text an d'Ännerungen tëscht de geläschte Versioune weisen",
'right-browsearchive' => 'Geläscht Säite sichen',
'right-undelete' => 'Eng Säit restauréieren',
'right-suppressrevision' => 'Virun den Administrateure verstoppte Versiounen nokucken a restauréieren',
Dëst kann en drastesche Changement fir eng populär Säit sinn;
verstitt w.e.g. d'Konsequenze vun ärer Handlung éier Dir dëst maacht.",
'movepagetalktext' => "D'associéiert Diskussiounssäit, am Fall wou eng do ass, gëtt automatesch matgeréckelt, '''ausser:'''
-*D'Säit gëtt an een anere Nummraum geréckelt.
+*D'Säit gëtt an een aneren Nummraum geréckelt.
*Et gëtt schonn eng Diskussiounssäit mat dësem Numm, oder
*Dir klickt d'Këschtchen ënnendrënner net un.
'articleexists' => 'Eng Säit mat dësem Numm gëtt et schonns, oder den Numm deen Dir gewielt hutt gëtt net akzeptéiert.
Wielt w.e.g. en aneren Numm.',
'cantmove-titleprotected' => "Dir kënnt keng Säit op dës Plaz réckelen, well deen neien Titel fir d'Uleeë gespaart ass.",
-'talkexists' => "D'Säit selwer gouf erfollegräich geréckelt, mä d'Diskussiounssäit konnt net mat eriwwergeholl gi well et schonns eng ënner deem neien Titel gëtt. W.e.g. setzt dës manuell zesummen.",
+'talkexists' => "D'Säit selwer gouf geréckelt, mä d'Diskussiounssäit konnt net mat eriwwergeholl gi well et schonns eng ënner deem neien Titel gëtt. W.e.g. setzt dës manuell zesummen.",
'movedto' => 'geréckelt op',
'movetalk' => 'Déi associéiert Diskussiounssäit matréckelen',
'move-subpages' => 'Ënnersäite (bis zu $1) réckelen',
'tooltip-save' => 'Ännerunge späicheren',
'tooltip-preview' => 'Kuckt är Ännerungen ouni ofzespäicheren, Benotzt dëst w.e.g. virum späicheren!',
'tooltip-diff' => 'Weist wéi eng Ännerungen Dir beim Text gemaach hutt.',
-'tooltip-compareselectedversions' => "D'Ënnerscheeder op dëser Säit tëschent den zwou gewielte Versioune weisen.",
+'tooltip-compareselectedversions' => "D'Ënnerscheeder op dëser Säit tëscht den zwou gewielte Versioune weisen.",
'tooltip-watch' => 'Dës Säit op Är Iwwerwaachungslëscht bäisetzen',
'tooltip-watchlistedit-normal-submit' => 'Säiten erofhuelen',
'tooltip-watchlistedit-raw-submit' => 'Iwwerwaachungslëscht aktualiséieren',
'noimages' => 'Keng Biller fonnt.',
'ilsubmit' => 'Sichen',
'bydate' => 'no Datum',
-'sp-newimages-showfrom' => 'Nei Biller weisen, ugefaangen den $1 ëm $2',
+'sp-newimages-showfrom' => 'Nei Biller weisen, ugefaangen de(n) $1 ëm $2',
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
'seconds' => '{{PLURAL:$1|enger Sekonn|$1 Sekonnen}}',
'version-poweredby-others' => 'anerer',
'version-poweredby-translators' => 'translatewiki.net Iwwersetzer',
'version-credits-summary' => "Mir soen dëse Persoune 'Merci' fir hir Mataarbecht u [[Special:Version|MediaWiki]].",
-'version-license-info' => "MediaWiki ass fräi Software; Dir kënnt se weiderginn an/oder s'änneren ënner de Bedingungen vun der GNU-General Public License esou wéi se vun der Free Softare Foundation publizéiert ass; entweder ënner der Versioun 2 vun der Lizenz, oder (no Ärem Choix) enger spéiderer Versioun.
+'version-license-info' => "MediaWiki ass fräi Software; Dir kënnt se weiderginn an/oder s'änneren ënner de Bedingunge vun der GNU-General Public License esou wéi se vun der Free Softare Foundation publizéiert ass; entweder ënner der Versioun 2 vun der Lizenz, oder (no Ärem Choix) enger spéiderer Versioun.
MediaWiki gëtt verdeelt an der Hoffnung datt se nëtzlech ass, awer OUNI IERGENDENG GARANTIE; ouni eng implizit Garantie vu Commercialisatioun oder Eegnung fir e bestëmmte Gebrauch. Kuckt d'GPL General Public License fir méi Informatiounen.
# External image whitelist
'external_image_whitelist' => "#Dës Zeil genee esou loosse wéi se ass<pre>
-#Schreift hei ënnendrënner Fragmenter vu regulären Ausdréck (just den Deel zwëschen den // aginn)
+#Schreift hei ënnendrënner Fragmenter vu regulären Ausdréck (just den Deel zwëscht den // aginn)
#Dës gi mat den URLe vu Biller aus externe Quelle verglach
#Wann d'Resultat positiv ass, gëtt d'Bild gewisen, soss gëtt d'Bild just als Link gewisen
#Zeilen, déi mat engem # ufänken, ginn als Bemierkung behandelt
-#Et gëtt en Ënnerscheed tëschent groussen a klenge Buschtawe gemaach
+#Et gëtt en Ënnerscheed tëscht groussen a klenge Buschtawe gemaach
#All regulär Ausdréck ënner dëser Zeil androen. Dës Zeil genee esou loosse wéi se ass</pre>",
'tag-filter-submit' => 'Filtrs',
'tag-list-wrapper' => '([[Special:Tags|{{PLURAL:$1|Iezīme|Iezīmes}}]]: $2)',
'tags-title' => 'Iezīmes',
+'tags-intro' => 'Šajā lapā uzskaitītas iezīmes, ar kurām programmatūra var atzīmēt labojumus, un to nozīme.',
'tags-tag' => 'Iezīmes nosaukums',
'tags-display-header' => 'Izmainīto sarakstu izskats',
'tags-description-header' => 'Nozīmes pilns apraksts',
'prefs-displaysearchoptions' => 'Pilihan paparan',
'prefs-displaywatchlist' => 'Pilihan paparan',
'prefs-diffs' => 'Beza',
+'prefs-help-prefershttps' => 'Keutamaan inu akan berkuatkuasa pada lain kali anda log masuk.',
# User preference: email validation using jQuery
'email-address-validity-valid' => 'Alamat e-mel adalah sah',
'dberr-problems' => 'Harap maaf. Tapak web ini dilanda masalah teknikal.',
'dberr-again' => 'Cuba tunggu selama beberapa minit dan muat semula.',
'dberr-info' => '(Tidak dapat menghubungi pelayan pangkalan data: $1)',
+'dberr-info-hidden' => '(Pelayan pangkalan data tidak dapat dihubungi)',
'dberr-usegoogle' => 'Buat masa ini, anda boleh cuba mencari melalui Google.',
'dberr-outofdate' => 'Sila ambil perhatian bahawa indeks mereka bagi kandungan kami mungkin sudah ketinggalan zaman.',
'dberr-cachederror' => 'Yang berikut ialah salinan bagi laman yang diminta yang diambil daripada cache, dan mungkin bukan yang terkini.',
'rotate-comment' => 'Imej diputar sebanyak $1 {{PLURAL:$1|darjah|darjah}} mengikut arah jam',
# Limit report
+'limitreport-title' => 'Data pemprofilan penghurai:',
'limitreport-cputime' => 'Penggunaan masa CPU',
'limitreport-cputime-value' => '$1 saat',
'limitreport-walltime' => 'Penggunaan masa nyata',
'deleteotherreason' => 'Aandere/extra reden:',
'deletereasonotherlist' => 'Aandere reden',
'deletereason-dropdown' => '*Redens veur t vortdoon van ziejen
-** Op vrage van de auteur
-** Schending van de auteursrechten
-** Vandelisme',
+** Op verzeuk van de auteur
+** Schending van auteursrecht
+** Vandalisme',
'delete-edit-reasonlist' => 'Redens veur t vortdoon bewarken',
'delete-toobig' => 'Disse zied hef n lange bewarkingsgeschiedenisse, meer as $1 {{PLURAL:$1|versie|versies}}.
t Vortdoon van dit soort ziejen is mit rechten bepark um t per ongelok versteuren van de warking van {{SITENAME}} te veurkoemen.',
'protect-otherreason' => 'Aandere reden:',
'protect-otherreason-op' => 'aandere reden',
'protect-dropdown' => '*Veulveurkomende redens veur beveiliging
-** Vandelisme
-** Ongewunste verwiezingen plaotsen
+** Te veul vandalisme
+** Te veul moekreklame
** Bewarkingsoorlog
** Zied mit veule bezeukers',
'protect-edit-reasonlist' => 'Redens veur beveiliging bewarken',
'blockip' => 'Gebruker blokkeren',
'blockip-title' => 'Gebruker blokkeren',
'blockip-legend' => 'n Gebruker of IP-adres blokkeren',
-'blockiptext' => 'Gebruuk dit formulier um n IP-adres of gebrukersnaam te blokkeren. t Is bedoeld um vandelisme te veurkoemen en mit in akkerderen mit t [[{{MediaWiki:Policy-url}}|beleid]]. Geef hieronder n reden op (bieveurbeeld op welke ziejen de vandelisme epleeg is)',
+'blockiptext' => 'Gebruuk dit formulier um n IP-adres of gebrukersnaam te blokkeren.
+t Is bedoeld um vandalisme te veurkoemen en mut akkederen mit t [[{{MediaWiki:Policy-url}}|beleid]].
+Geef hieronder n reden op (bieveurbeeld op welke ziejen de vandalisme epleegd is).',
'ipadressorusername' => 'IP-adres of gebrukersnaam',
'ipbexpiry' => 'Verlöp nao',
'ipbreason' => 'Reden:',
'continue-editing' => 'Naar het bewerkingsvenster gaan',
'previewconflict' => 'Deze voorvertoning geeft aan hoe de tekst in het bovenste veld eruit ziet als u deze opslaat.',
'session_fail_preview' => "'''Excuses, uw bewerking is niet opgeslagen omdat de sessiegegevens verloren zijn gegaan.'''
-Probeer het altublieft opnieuw.
-Als het dan nog niet lukt, [[Special:UserLogout|meld uzelf dan af]] en vervolgens weer aan.
-
-<!-- Aanspreekvorm \"probeert U\" was overbodig; bovendien is de hoofdletter gereserveerd voor het aanspreken van God -->",
+Probeer het opnieuw.
+Als het dan nog niet lukt, [[Special:UserLogout|meld uzelf dan af]] en vervolgens weer aan.",
'session_fail_preview_html' => "'''Uw bewerking is niet verwerkt, omdat de sessiegegevens verloren zijn gegaan.'''
''Omdat in {{SITENAME}} ruwe HTML is ingeschakeld, is een voorvertoning niet mogelijk als bescherming tegen aanvallen met JavaScript.''
* @author Beau
* @author BeginaFelicysym
* @author Chrumps
+ * @author Clamira
* @author Cysioland
* @author Debeet
* @author Derbeth
Wpisz poprawny adres e‐mail lub wyczyść pole.',
'cannotchangeemail' => 'Na tej wiki nie ma możliwości zmiany adresu e‐mail przypisanego do konta.',
'emaildisabled' => 'Ta witryna nie może wysłać wiadomości e-mail.',
-'accountcreated' => 'Konto zostało utworzone',
+'accountcreated' => 'Utworzono konto',
'accountcreatedtext' => 'Konto dla [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|dyskusja]]) zostało utworzone.',
'createaccount-title' => 'Utworzenie konta w {{GRAMMAR:MS.lp|{{SITENAME}}}}',
'createaccount-text' => 'Ktoś utworzył w {{GRAMMAR:MS.lp|{{SITENAME}}}} ($4), podając Twój adres e‐mail, konto „$2”. Aktualnym hasłem jest „$3”.
'upload_directory_missing' => 'Katalog dla przesyłanych plików ($1) nie istnieje i nie może zostać utworzony przez serwer WWW.',
'upload_directory_read_only' => 'Serwer nie może zapisywać do katalogu ($1) przeznaczonego na przesyłane pliki.',
'uploaderror' => 'Błąd wysyłania',
-'upload-recreate-warning' => "'''Uwaga – plik o tej nazwie został wcześniej usunięty lub przrniesiony.'''
+'upload-recreate-warning' => "'''Uwaga: plik o tej nazwie został wcześniej usunięty lub przeniesiony.'''
Poniżej znajduje się rejestr usunięć i zmian nazwy tej strony:",
'uploadtext' => "Użyj poniższego formularza do przesłania plików.
** Naruszenie praw autorskich
** Wandalizm',
'delete-edit-reasonlist' => 'Edytuj listę przyczyn usunięcia',
-'delete-toobig' => 'Ta strona ma bardzo długą historię edycji, ponad $1 {{PLURAL:$1|zmianę|zmiany|zmian}}.
-Usunięcie jej mogłoby spowodować zakłócenia w pracy {{GRAMMAR:D.lp|{{SITENAME}}}} i dlatego zostało ograniczone.',
-'delete-warning-toobig' => 'Ta strona ma bardzo długą historię edycji, ponad $1 {{PLURAL:$1|zmianę|zmiany|zmian}}.
+'delete-toobig' => 'Ta strona ma bardzo długą historię edycji – ponad $1 {{PLURAL:$1|zmianę|zmiany|zmian}}.<br />
+Usuwanie jej zostało ograniczone ze względu na możliwość zakłócenia pracy {{GRAMMAR:D.lp|{{SITENAME}}}}.',
+'delete-warning-toobig' => 'Ta strona ma bardzo długą historię edycji – ponad $1 {{PLURAL:$1|zmianę|zmiany|zmian}}.<br />
Bądź ostrożny, ponieważ usunięcie jej może spowodować zakłócenia w pracy {{GRAMMAR:D.lp|{{SITENAME}}}}.',
# Rollback
'changeemail-no-info' => 'A dev esse intrà ant ël sistema për andé diretament a costa pàgina.',
'changeemail-oldemail' => 'Adrëssa ëd pòsta eletrònica atual:',
'changeemail-newemail' => 'Adrëssa ëd pòsta eletrònica neuva:',
-'changeemail-none' => '(gnun)',
-'changeemail-password' => 'Toa ciav ëd {{SITENAME}}:',
+'changeemail-none' => '(gnun-a)',
+'changeemail-password' => 'Soa ciav su {{SITENAME}}:',
'changeemail-submit' => "Cangé l'adrëssa ëd pòsta eletrònica",
-'changeemail-cancel' => 'Scancela',
+'changeemail-cancel' => 'Anulé',
+
+# Special:ResetTokens
+'resettokens' => 'Riamposté ij geton',
+'resettokens-text' => "Ambelessì a peul riamposté ij geton ch'a permëtto d'acede a chèich dàit privà associà a sò cont.
+
+A dovrìa felo si për asar chiel a l'ha partagiaje con cheidun o si sò cont a l'é stàit compromëttù.",
+'resettokens-no-tokens' => 'A-i é gnun geton da riamposté.',
+'resettokens-legend' => 'Riamposté ij geton.',
+'resettokens-tokens' => 'Geton:',
+'resettokens-token-label' => '$1 (valor atual: $2)',
+'resettokens-watchlist-token' => "Geton për ël fluss an sl'aragnà (Atom/RSS) ëd [[Special:Watchlist|modìfiche a le pàgine che as ten sot-euj]]",
+'resettokens-done' => 'Geton riampostà.',
+'resettokens-resetbutton' => 'Riamposté ij geton selessionà',
# Edit page toolbar
'bold_sample' => 'Test an grassèt',
'link_tip' => 'Anliura interna',
'extlink_sample' => "http://www.example.com tìtol dl'anliura",
'extlink_tip' => 'Anliura esterna (che as visa dë buté ël prefiss http://)',
-'headline_sample' => "Antestassion dl'artìcol",
+'headline_sample' => 'Test dël tìtol',
'headline_tip' => 'Antestassion dë scond livel',
-'nowiki_sample' => 'Che a buta ël test nen formatà ambelessì',
-'nowiki_tip' => 'Lassé un tòch ëd test fòra dla formatassion dla wiki',
+'nowiki_sample' => 'Che a buta ël test brut ambelessì',
+'nowiki_tip' => 'Lassé un tòch ëd test fòra dla sintassi dla wiki',
'image_sample' => 'Esempi.jpg',
-'image_tip' => 'Figura anglobà ant ël test',
+'image_tip' => 'Archivi anglobà',
'media_sample' => 'Esempi.ogg',
'media_tip' => "Anliura a n'archivi multimedial",
-'sig_tip' => 'Firma butand data e ora',
+'sig_tip' => "Soa signadura con la data e l'ora",
'hr_tip' => 'Riga orisontal (da dovresse nen tròp soèns)',
# Edit pages
* $1 - a link which points to a diff, shown as a plain link
See also:
* {{msg-mw|Enotif lastvisited}}',
-'enotif_anon_editor' => 'User name in an e-mail notification when referring to an anonymous user. Parameters:
-* $1 is the anonymous user name (i.e. an IP address).',
+'enotif_anon_editor' => 'User name in an email notification when referring to an anonymous user. Parameters:
+* $1 - the anonymous user name (i.e. an IP address).',
'enotif_body' => 'Text of a notification email sent when a watched page has been edited or deleted.
[[File:Screenshot_MediaWiki_e-mail_notifier.PNG|150px|right]]
* $1 - the number of years',
'ago' => 'Phrase for indicating how long ago something happened. Parameters:
* $1 - some kind of timestamp
-{{Identical|$1 ago}}',
+{{Identical|Ago}}',
'just-now' => 'Phrase for indicating something happened just now.',
# Human-readable timestamps
'createacct-another-username-ph' => 'Введите имя вашей учётной записи',
'yourpassword' => 'Пароль:',
'userlogin-yourpassword' => 'Пароль',
-'userlogin-yourpassword-ph' => 'Введите ваш пароль',
+'userlogin-yourpassword-ph' => 'Введите свой пароль',
'createacct-yourpassword-ph' => 'Введите пароль',
'yourpasswordagain' => 'Повторный набор пароля:',
'createacct-yourpasswordagain' => 'Подтвердите пароль',
# Special:ResetTokens
'resettokens' => 'Сбросить токены',
+'resettokens-no-tokens' => 'Нет токенов для сброса.',
+'resettokens-legend' => 'Сбросить токены',
'resettokens-tokens' => 'Токены:',
'resettokens-token-label' => '$1 (текущее значение: $2)',
+'resettokens-watchlist-token' => 'Токен для веб-канала (Atom/RSS) [[Special:Watchlist|изменений страниц в вашем списке наблюдения]]',
+'resettokens-done' => 'Токены сброшены.',
'resettokens-resetbutton' => 'Сбросить выбранные токены',
# Edit page toolbar
'recentchangesdays-max' => '(не более $1 {{PLURAL:$1|дня|дней|дней}})',
'recentchangescount' => 'Количество правок, отображаемое по умолчанию:',
'prefs-help-recentchangescount' => 'Включает свежие правки, истории страниц, журналы.',
+'prefs-help-watchlist-token2' => 'Это секретный ключ для веб-канала вашего списка наблюдений.
+Любой, кто знает его, сможет читать ваш список наблюдения, поэтому не сообщайте его другим. [[Special:ResetTokens|Нажмите здесь, если вам нужно сбросить его]].',
'savedprefs' => 'Ваши настройки сохранены.',
'timezonelegend' => 'Часовой пояс:',
'localtime' => 'Местное время:',
'prefs-displaywatchlist' => 'Настройки отображения',
'prefs-tokenwatchlist' => 'Токен',
'prefs-diffs' => 'Разница версий',
-'prefs-help-prefershttps' => 'ÐÑ\82а наÑ\81Ñ\82Ñ\80ойка бÑ\83деÑ\82 введена в Ñ\81ледÑ\83Ñ\8eÑ\89ий Ñ\80аз когда вÑ\8b пÑ\80едÑ\81Ñ\82авиÑ\82еÑ\81Ñ\8c системе.',
+'prefs-help-prefershttps' => 'ÐÑ\82а наÑ\81Ñ\82Ñ\80ойка бÑ\83деÑ\82 пÑ\80именена поÑ\81ле Ñ\81ледÑ\83Ñ\8eÑ\89его пÑ\80едÑ\81Ñ\82авлениÑ\8f системе.',
# User preference: email validation using jQuery
'email-address-validity-valid' => 'Выглядит корректно',
'pageswithprop-text' => 'Здесь перечислены страницы, у которых были вручную переопределены отдельные свойства.',
'pageswithprop-prop' => 'Название свойства:',
'pageswithprop-submit' => 'Найти',
-'pageswithprop-prophidden-long' => 'длинное значение текстового свойства скрыто ($1 килобайт)',
+'pageswithprop-prophidden-long' => 'длинное значение текстового свойства скрыто ($1)',
'pageswithprop-prophidden-binary' => 'значение двоичного свойства скрыто ($1)',
'doubleredirects' => 'Двойные перенаправления',
'rotate-comment' => 'Изображение повёрнуто на $1 градус{{PLURAL:$1||а|ов}} по часовой стрелке',
# Limit report
+'limitreport-cputime' => 'Использование времени процессора',
+'limitreport-walltime' => 'Использование в режиме реального времени',
+'limitreport-ppgeneratednodes' => 'Количество сгенерированных препроцессором узлов',
'limitreport-postexpandincludesize-value' => '$1/$2 байт',
+'limitreport-templateargumentsize' => 'Размер аргумента шаблона',
'limitreport-templateargumentsize-value' => '$1/$2 байт',
+'limitreport-expansiondepth' => 'Наибольшая глубина расширения',
+'limitreport-expensivefunctioncount' => 'Количество «дорогих» функций анализатора',
);
'rc_categories_any' => 'akékoľvek',
'rc-change-size-new' => '$1 {{PLURAL:$1|bajt|bajty|bajtov}} po zmene',
'newsectionsummary' => '/* $1 */ nová sekcia',
-'rc-enhanced-expand' => 'Zobraziť podrobnosti (vyžaduje JavaScript)',
+'rc-enhanced-expand' => 'Zobraziť podrobnosti',
'rc-enhanced-hide' => 'Skryť podrobnosti',
'rc-old-title' => 'pôvodne vytvorené ako "$1"',
'tog-oldsig' => 'Текући потпис:',
'tog-fancysig' => 'Сматрај потпис као викитекст (без самоповезивања)',
'tog-uselivepreview' => 'Користи тренутан преглед (експериментално)',
-'tog-forceeditsummary' => 'Ð\9eпомени ме пÑ\80и Ñ\83ноÑ\81Ñ\83 пÑ\80азног опиÑ\81а',
+'tog-forceeditsummary' => 'УпозоÑ\80и ме када не Ñ\83неÑ\81ем опиÑ\81 измене',
'tog-watchlisthideown' => 'Сакриј моје измене са списка надгледања',
'tog-watchlisthidebots' => 'Сакриј измене ботова са списка надгледања',
'tog-watchlisthideminor' => 'Сакриј мање измене са списка надгледања',
'category_header' => 'Странице у категорији „$1“',
'subcategories' => 'Поткатегорије',
'category-media-header' => 'Датотеке у категорији „$1“',
-'category-empty' => "''Ова категорија тренутно не садржи странице или датотеке.''",
+'category-empty' => "<div style=\"margin:2em 1em 0 1em; padding:0.5em; border:1px solid #AAA; text-align:center;\">''Ова категорија тренутно не садржи странице или датотеке.''</div>",
'hidden-categories' => '{{PLURAL:$1|Сакривена категорија|Сакривене категорије}}',
'hidden-category-category' => 'Сакривене категорије',
'category-subcat-count' => '{{PLURAL:$2|Ова категорија садржи само следећу поткатегорију.|Ова категорија има {{PLURAL:$1|следећу поткатегорију|следеће $1 поткатегорије|следећих $1 поткатегорија}}, од укупно $2.}}',
'''({{int:last}})''' – разлика с претходном изменом, '''{{int:minoreditletter}}''' – мала измена",
'history-fieldset-title' => 'Преглед историје',
'history-show-deleted' => 'само обрисано',
-'histfirst' => 'Ð\9dајстарије',
-'histlast' => 'Ð\9dајновије',
+'histfirst' => 'најстарије',
+'histlast' => 'најновије',
'historysize' => '({{PLURAL:$1|1 бајт|$1 бајта|$1 бајтова}})',
'historyempty' => '(празно)',
'badsiglength' => 'Ваш потпис је предугачак.
Не сме бити дужи од $1 {{PLURAL:$1|знака|знака|знакова}}.',
'yourgender' => 'Како желите да се представите?',
-'gender-unknown' => 'Ð\9dе пÑ\80евиÑ\88е деÑ\82аÑ\99но',
+'gender-unknown' => 'Ð\9dе желим да Ñ\81е пÑ\80едÑ\81Ñ\82авим',
'gender-male' => 'Он уређује вики странице',
'gender-female' => 'Она уређује вики странице',
'prefs-help-gender' => 'Необавезно: користи се за исправно обраћање софтвера корисницима, зависно од њиховог пола.
'prefs-i18n' => 'Интернационализација',
'prefs-signature' => 'Потпис',
'prefs-dateformat' => 'Формат датума',
-'prefs-timeoffset' => 'Ð\92Ñ\80еменÑ\81ко одÑ\81Ñ\82Ñ\83паÑ\9aе',
+'prefs-timeoffset' => 'Ð\92Ñ\80еменÑ\81ка Ñ\80азлика',
'prefs-advancedediting' => 'Главна подешавања',
'prefs-editor' => 'Уређивач',
'prefs-preview' => 'Претпреглед',
'uploadwarning-text' => 'Измените опис датотеке и покушајте поново.',
'savefile' => 'Сачувај датотеку',
'uploadedimage' => '{{GENDER:|је послао|је послала|је послао}} „[[$1]]“',
-'overwroteimage' => '{{GENDER:|је послао|је послала|је послао}} ново издање „[[$1]]“',
+'overwroteimage' => '{{GENDER:|је послао|је послала}} нову верзију датотеке „[[$1]]“',
'uploaddisabled' => 'Отпремање је онемогућено.',
'copyuploaddisabled' => 'Слање путем URL адресе је онемогућено.',
'uploadfromurl-queued' => 'Слање је стављено на списак чекања.',
# File description page
'file-anchor-link' => 'Датотека',
'filehist' => 'Историја датотеке',
-'filehist-help' => 'Кликните на датум/време да видите тадашње издање датотеке.',
+'filehist-help' => 'Кликните на датум/време да видите тадашњу верзију датотеке.',
'filehist-deleteall' => 'обриши све',
'filehist-deleteone' => 'обриши',
'filehist-revert' => 'врати',
# Metadata
'metadata' => 'Метаподаци',
-'metadata-help' => 'Ова датотека садржи додатне податке који вероватно долазе од дигигалних фотоапарата или скенера.
+'metadata-help' => 'Ова датотека садржи додатне податке који вероватно долазе од дигиталног фотоапарата или скенера.
Ако је првобитно стање датотеке промењено, могуће је да неки детаљи не описују измењену датотеку.',
'metadata-expand' => 'Прикажи детаље',
'metadata-collapse' => 'Сакриј детаље',
'tog-hidepatrolled' => 'Sakrij pregledane izmene u spisku skorašnjih izmena',
'tog-newpageshidepatrolled' => 'Sakrij pregledane stranice sa spiska novih stranica',
'tog-extendwatchlist' => 'Proširi spisak nadgledanja za prikaz svih izmena, ne samo skorašnjih',
-'tog-usenewrc' => 'Promene u grupi po stranici u spisku skorašnjih izmena i nadgledanih stranica (zahteva javaskript)',
+'tog-usenewrc' => 'Promene u grupi po stranici u spisku skorašnjih izmena i nadgledanih stranica',
'tog-numberheadings' => 'Samostalno numeriši podnaslove',
-'tog-showtoolbar' => 'Traka s alatkama za uređivanje (javaskript)',
-'tog-editondblclick' => 'Uređivanje stranica dvostrukim klikom (potrebna JavaScript-а)',
+'tog-showtoolbar' => 'Prikaži traku s alatkama za uređivanje',
+'tog-editondblclick' => 'Uređivanje stranica dvostrukim klikom',
'tog-editsection' => 'Veze za uređivanje pojedinačnih odeljaka',
-'tog-editsectiononrightclick' => 'Uređivanje odeljaka desnim klikom na njihove naslove (javaskript)',
+'tog-editsectiononrightclick' => 'Uređivanje odeljaka desnim klikom na njihove naslove',
'tog-showtoc' => 'Prikaži sadržaj stranica koje imaju više od tri podnaslova',
-'tog-rememberpassword' => 'Zapamti me na ovom pregledaču (najduže $1 {{PLURAL:$1|dan|dana|dana}})',
+'tog-rememberpassword' => 'Zapamti me na ovom pregledaču (najduže $1 {{PLURAL:$1|dan|dana}})',
'tog-watchcreations' => 'Dodaj stranice koje napravim i datoteke koje pošaljem u spisak nadgledanja',
'tog-watchdefault' => 'Dodaj stranice i datoteke koje izmenim u spisak nadgledanja',
'tog-watchmoves' => 'Dodaj stranice i datoteke koje premestim u spisak nadgledanja',
'tog-shownumberswatching' => 'Prikaži broj korisnika koji nadgledaju',
'tog-oldsig' => 'Tekući potpis:',
'tog-fancysig' => 'Smatraj potpis kao vikitekst (bez samopovezivanja)',
-'tog-uselivepreview' => 'Koristi trenutan pregled (javaskript, probna mogućnost)',
-'tog-forceeditsummary' => 'Opomeni me pri unosu praznog opisa',
+'tog-uselivepreview' => 'Koristi trenutan pregled (eksperimentalno)',
+'tog-forceeditsummary' => 'Upozori me kada ne unesem opis izmene',
'tog-watchlisthideown' => 'Sakrij moje izmene sa spiska nadgledanja',
'tog-watchlisthidebots' => 'Sakrij izmene botova sa spiska nadgledanja',
'tog-watchlisthideminor' => 'Sakrij manje izmene sa spiska nadgledanja',
'category_header' => 'Stranice u kategoriji „$1“',
'subcategories' => 'Potkategorije',
'category-media-header' => 'Datoteke u kategoriji „$1“',
-'category-empty' => "''Ova kategorija trenutno ne sadrži stranice ili datoteke.''",
+'category-empty' => "<div style=\"margin:2em 1em 0 1em; padding:0.5em; border:1px solid #AAA; text-align:center;\">''Ova kategorija trenutno ne sadrži stranice ili datoteke.''</div>",
'hidden-categories' => '{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}}',
'hidden-category-category' => 'Sakrivene kategorije',
'category-subcat-count' => '{{PLURAL:$2|Ova kategorija sadrži samo sledeću potkategoriju.|Ova kategorija ima {{PLURAL:$1|sledeću potkategoriju|sledeće $1 potkategorije|sledećih $1 potkategorija}}, od ukupno $2.}}',
'newwindow' => '(otvara u novom prozoru)',
'cancel' => 'Otkaži',
'moredotdotdot' => 'Više…',
-'morenotlisted' => 'Više nije prikazano...',
+'morenotlisted' => 'Ova lista nije kompletna.',
'mypage' => 'Stranica',
'mytalk' => 'Razgovor',
'anontalk' => 'Razgovor za ovu IP adresu',
'loginreqlink' => 'prijavljeni',
'loginreqpagetext' => 'Morate biti $1 da biste videli druge stranice.',
'accmailtitle' => 'Lozinka je poslata.',
-'accmailtext' => 'Lozinka za {{GENDER:$1|korisnika|korisnicu|korisnika}} [[User talk:$1|$1]] je poslata na $2.
-
-Nakon prijave, lozinka se može promeniti [[Special:ChangePassword|ovde]].',
+'accmailtext' => 'Lozika za {{GENDER:$1|korisnika|korisnicu}} [[User talk:$1|$1]] je poslata na $2. Nakon prijave, lozinka se može promeniti [[Special:ChangePassword|ovde]].',
'newarticle' => '(novi)',
'newarticletext' => 'Došli ste na stranicu koja još ne postoji.
Da biste je napravili, počnite kucati u prozor ispod ovog teksta (pogledajte [[{{MediaWiki:Helppage}}|stranicu za pomoć]]).
'prefs-emailconfirm-label' => 'Potvrda e-adrese:',
'youremail' => 'E-adresa:',
'username' => '{{GENDER:$1|Korisničko ime}}:',
-'uid' => 'Korisnički IB:',
+'uid' => '{{GENDER:$1|Korisnički}} ID:',
'prefs-memberingroups' => '{{GENDER:$2|Korisnik|Korisnica}} je član {{PLURAL:$1|grupe|grupa}}:',
'prefs-memberingroups-type' => '$1',
'prefs-registration' => 'Vreme upisa:',
Proverite oznake HTML.',
'badsiglength' => 'Vaš potpis je predugačak.
Ne sme biti duži od $1 {{PLURAL:$1|znaka|znaka|znakova}}.',
-'yourgender' => 'Pol:',
-'gender-unknown' => 'nenaznačen',
-'gender-male' => 'muški',
-'gender-female' => 'ženski',
+'yourgender' => 'Kako želite da se predstavite?',
+'gender-unknown' => 'Ne želim da se predstavim',
+'gender-male' => 'On uređuje viki stranice',
+'gender-female' => 'Ona uređuje viki stranice',
'prefs-help-gender' => 'Neobavezno: koristi se za ispravno obraćanje softvera korisnicima, zavisno od njihovog pola.
Ovaj podatak će biti javan.',
'email' => 'E-adresa',
'prefs-i18n' => 'Internacionalizacija',
'prefs-signature' => 'Potpis',
'prefs-dateformat' => 'Format datuma',
-'prefs-timeoffset' => 'Vremensko odstupanje',
+'prefs-timeoffset' => 'Vremenska razlika',
'prefs-advancedediting' => 'Glavna podešavanja',
'prefs-advancedrc' => 'Napredne postavke',
'prefs-advancedrendering' => 'Napredne postavke',
'group-user-member' => '{{GENDER:$1|korisnik|korisnica|korisnik}}',
'group-autoconfirmed-member' => '{{GENDER:$1|automatski potvrđen korisnik|automatski potvrđena korisnica|automatski potvrđen korisnik}}',
'group-bot-member' => '{{GENDER:$1|bot}}',
-'group-sysop-member' => '{{GENDER:$1|administrator|administratorka|administrator}}',
-'group-bureaucrat-member' => '{{GENDER:$1|birokrata|birokratkinja|birokrata}}',
+'group-sysop-member' => '{{GENDER:$1|administrator|administratorka}}',
+'group-bureaucrat-member' => '{{GENDER:$1|birokrata|birokratkinja}}',
'group-suppress-member' => '{{GENDER:$1|revizor|revizorka|revizor}}',
'grouppage-user' => '{{ns:project}}:Korisnici',
'right-reupload-shared' => 'menjanje datoteka na deljenom skladištu multimedije',
'right-upload_by_url' => 'otpremanje datoteka sa veb adrese',
'right-purge' => 'čišćenje keš memorije stranice bez potvrde',
-'right-autoconfirmed' => 'uređivanje poluzaštićenih stranica',
+'right-autoconfirmed' => 'Not be affected by IP-based rate limits',
'right-bot' => 'smatranje izmena kao automatski proces',
'right-nominornewtalk' => 'neposedovanje malih izmena na stranicama za razgovor otvara prozor za nove poruke',
'right-apihighlimits' => 'korišćenje viših granica za upite iz API-ja',
'reuploaddesc' => 'Nazad na obrazac za otpremanje',
'upload-tryagain' => 'Pošalji izmenjeni opis datoteke',
'uploadnologin' => 'Niste prijavljeni',
-'uploadnologintext' => 'Morate biti [[Special:UserLogin|prijavljeni]] da biste otpremali datoteke.',
+'uploadnologintext' => 'Morate biti $1 da biste otpremali datoteke.',
'upload_directory_missing' => 'Fascikla za slanje ($1) nedostaje i server je ne može napraviti.',
'upload_directory_read_only' => 'Server ne može da piše po fascikli za slanje ($1).',
'uploaderror' => 'Greška pri otpremanju',
'uploadwarning-text' => 'Izmenite opis datoteke i pokušajte ponovo.',
'savefile' => 'Sačuvaj datoteku',
'uploadedimage' => '{{GENDER:|je poslao|je poslala|je poslao}} „[[$1]]“',
-'overwroteimage' => '{{GENDER:|je poslao|je poslala|je poslao}} novo izdanje „[[$1]]“',
+'overwroteimage' => '{{GENDER:|je poslao|je poslala}} novu verziju datoteke „[[$1]]“',
'uploaddisabled' => 'Otpremanje je onemogućeno.',
'copyuploaddisabled' => 'Slanje putem URL adrese je onemogućeno.',
'uploadfromurl-queued' => 'Slanje je stavljeno na spisak čekanja.',
'upload_source_file' => ' (datoteka na vašem računaru)',
# Special:ListFiles
-'listfiles-summary' => 'Ova posebna stranica prikazuje sve poslate datoteke.
-Kad je poređano po korisniku, popis prikazuje samo one datoteke čije je poslednje izdanje postavio taj korisnik.',
+'listfiles-summary' => 'Ova posebna stranica prikazuje sve poslate datoteke.',
'listfiles_search_for' => 'Naziv datoteke:',
'imgfile' => 'datoteka',
'listfiles' => 'Spisak datoteka',
# File description page
'file-anchor-link' => 'Datoteka',
'filehist' => 'Istorija datoteke',
-'filehist-help' => 'Kliknite na datum/vreme da vidite tadašnje izdanje datoteke.',
+'filehist-help' => 'Kliknite na datum/vreme da vidite tadašnju verziju datoteke.',
'filehist-deleteall' => 'obriši sve',
'filehist-deleteone' => 'obriši',
'filehist-revert' => 'vrati',
'watchnologintext' => 'Morate biti [[Special:UserLogin|prijavljeni]] da biste menjali spisak nadgledanja.',
'addwatch' => 'Dodaj na spisak nadgledanja',
'addedwatchtext' => 'Stranica „[[:$1]]“ je dodata na vaš [[Special:Watchlist|spisak nadgledanja]].
-Buduće izmene ove stranice i njene stranice za razgovor biće navedene ovde, a stranica će biti <b>podebljana</b> u [[Special:RecentChanges|spisku skorašnjih izmena]] da bi se lakše uočila.
-
-Ukoliko budete želeli da uklonite stranicu sa spiska nadgledanja, kliknite opet na zvezdicu u gornjoj paleti.',
+Buduće izmene ove stranice i njene stranice za razgovor biće navedene tamo.',
'removewatch' => 'Ukloni sa spiska nadgledanja',
'removedwatchtext' => 'Stranica „[[:$1]]“ je uklonjena s vašeg [[Special:Watchlist|spiska nadgledanja]].',
'watch' => 'Nadgledaj',
'blanknamespace' => '(Glavno)',
# Contributions
-'contributions' => 'Korisnički doprinosi',
+'contributions' => '{{GENDER:$1|Korisnički}} doprinosi',
'contributions-title' => 'Doprinosi {{GENDER:$1|korisnika|korisnice|korisnika}} $1',
'mycontris' => 'Doprinosi',
'contribsub2' => 'Za $1 ($2)',
'pageinfo-length' => 'Dužina stranice (u bajtovima)',
'pageinfo-article-id' => 'ID stranice',
'pageinfo-language' => 'Jezik sadržaja stranice',
-'pageinfo-robot-policy' => 'Status pretraživača',
+'pageinfo-robot-policy' => 'Indeksiranje od strane robota',
'pageinfo-robot-index' => 'Dozvoljeno',
'pageinfo-robot-noindex' => 'Nije dozvoljeno',
'pageinfo-views' => 'Broj pregleda',
'pageinfo-watchers' => 'Broj nadgledača stranica',
'pageinfo-few-watchers' => 'Manje od $1 {{PLURAL:$1|pratioca|pratilaca}}',
-'pageinfo-redirects-name' => 'Preusmeravanja na stranicu',
+'pageinfo-redirects-name' => 'Broj preusmerenja na ovu stranicu',
'pageinfo-subpages-name' => 'Podstranice ove stranice',
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|preusmerenje|preusmerenja|preusmerenja}}; $3 {{PLURAL:$3|nepreusmerenje|nepreusmerenja|nepreusmerenja}})',
'pageinfo-firstuser' => 'Autor stranice',
# Metadata
'metadata' => 'Metapodaci',
-'metadata-help' => 'Ova datoteka sadrži dodatne podatke koji verovatno dolaze od digigalnih fotoaparata ili skenera.
+'metadata-help' => 'Ova datoteka sadrži dodatne podatke koji verovatno dolaze od digitalnog fotoaparata ili skenera.
Ako je prvobitno stanje datoteke promenjeno, moguće je da neki detalji ne opisuju izmenjenu datoteku.',
'metadata-expand' => 'Prikaži detalje',
'metadata-collapse' => 'Sakrij detalje',
'exif-compression-34712' => 'JPEG2000',
'exif-copyrighted-true' => 'Zaštićeno autorskim pravom',
-'exif-copyrighted-false' => 'Javno vlasništvo',
+'exif-copyrighted-false' => 'Status autorskih prava nije podešen',
'exif-photometricinterpretation-2' => 'RGB',
'exif-photometricinterpretation-6' => 'YCbCr',
'tog-noconvertlink' => 'ปิดใช้งานการแปลงชื่อเรื่องของลิงก์',
'tog-norollbackdiff' => 'ไม่แสดงการเปลี่ยนแปลงหลังดำเนินการย้อนกลับฉุกเฉิน',
'tog-useeditwarning' => 'เตือนฉัน เมื่อฉันกำลังจะออกจากหน้าแก้ไขโดยมีข้อมูลที่ยังไม่ได้บันทึก',
+'tog-prefershttps' => 'ใช้การเชื่อมต่อปลอดภัยทุกครั้งเมื่อล็อกอิน',
'underline-always' => 'เสมอ',
'underline-never' => 'ไม่เคย',
'createacct-emailoptional' => 'ที่อยู่อีเมล (เลือกไม่ใส่ได้)',
'createacct-email-ph' => 'กรอกที่อยู่อีเมล',
'createacct-another-email-ph' => 'กรอกที่อยู่อีเมล',
-'createaccountmail' => 'ใช้รหัสผ่านสุ่มชั่วคราวและส่งไปยังที่อยู่อีเมลที่ระบุด้านล่าง',
+'createaccountmail' => 'ใช้รหัสผ่านสุ่มชั่วคราวและส่งไปยังที่อยู่อีเมลที่ระบุ',
'createacct-realname' => 'ชื่อจริง (เลือกไม่ใส่ได้)',
'createaccountreason' => 'เหตุผล:',
'createacct-reason' => 'เหตุผล',
กรุณาล็อกอินอีกครั้งหลังได้รับอีเมล',
'blocked-mailpassword' => 'เลขที่อยู่ไอพีของคุณถูกบล็อกมิให้แก้ไข ฉะนั้น จึงไม่ได้รับอนุญาตให้ใช้ฟังก์ชันขอกู้รหัสผ่านเพื่อป้องกันการกระทำผิด',
'eauthentsent' => 'อีเมลยืนยันได้ถูกส่งไปที่อยู่อีเมลที่เสนอ ก่อนที่อีเมลจะถูกส่งไปที่ชื่อบัญชีนั้น คุณต้องปฏิบัติตามคำแนะนำในอีเมลเพื่อยืนยันว่าบัญชีนั้นเป็นของคุณจริง ๆ',
-'throttled-mailpassword' => 'ตัวเตือนรหัสผ่านได้ถูกส่งไปแล้วใน $1 ชั่วโมงที่ผ่านมา ตัวเตือนรหัสผ่านนี้จะถูกส่งได้หนึ่งครั้งต่อ $1 ชั่วโมงเท่านั้น เพื่อป้องกันการกระทำผิด',
+'throttled-mailpassword' => 'อีเมลตั้งรหัสผ่านใหม่ถูกส่งไปแล้วใน $1 ชั่วโมงที่ผ่านมา
+อีเมลตั้งรหัสผ่านใหม่จะส่งไปหนึ่งครั้งต่อ $1 ชั่วโมงเท่านั้น เพื่อป้องกันการกระทำที่ไม่ถูกต้อง',
'mailerror' => 'ข้อผิดพลาดในการส่งเมล: $1',
'acct_creation_throttle_hit' => 'ผู้เข้าชมวิกินี้ที่ใช้เลขที่อยู่ไอพีของคุณ ได้สร้างบัญชีแล้ว $1 บัญชีในวันที่ผ่านมา ซึ่งเป็นจำนวนสูงสุดที่อนุญาตในช่วงเวลาดังกล่าว
จึงส่งผลให้ผู้เข้าชมที่ใช้เลขที่อยู่ไอพีนี้ ไม่สามารถสร้างบัญชีได้อีกในขณะนี้',
'passwordreset-capture-help' => 'หากคุณเลือกกล่องนี้ อีเมลดังกล่าว (พร้อมรหัสผ่านชั่วคราว) จะแสดงแก่คุณ เช่นเดียวกับส่งไปยังผู้ใช้',
'passwordreset-email' => 'ที่อยู่อีเมล:',
'passwordreset-emailtitle' => 'รายละเอียดบัญชีบน {{SITENAME}}',
-'passwordreset-emailtext-ip' => 'à¹\83à¸\84รà¸\9aาà¸\87à¸\84à¸\99 (à¸\8bึà¹\88à¸\87à¸à¸²à¸\88à¹\80à¸\9bà¹\87à¸\99à¸\84ุà¸\93 à¸\97ีà¹\88à¹\83à¸\8aà¹\89à¹\80ลà¸\82à¸\97ีà¹\88à¸à¸¢à¸¹à¹\88à¹\84à¸à¸\9eี $1) à¸\82à¸à¸\95ัวà¹\80à¸\95ืà¸à¸\99รายละà¹\80à¸à¸µà¸¢à¸\94à¸\9aัà¸\8dà¸\8aีà¸\82à¸à¸\87à¸\84ุà¸\93à¸\9aà¸\99 {{SITENAME}} ($4) บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
+'passwordreset-emailtext-ip' => 'à¸\9aาà¸\87à¸\84à¸\99 (à¸\8bึà¹\88à¸\87à¸à¸²à¸\88à¹\80à¸\9bà¹\87à¸\99à¸\84ุà¸\93 à¸\88าà¸\81à¹\80ลà¸\82à¸\97ีà¹\88à¸à¸¢à¸¹à¹\88à¹\84à¸à¸\9eี $1) รà¹\89à¸à¸\87à¸\82à¸à¸\81ารà¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¸\82à¸à¸\87à¸\84ุà¸\93à¹\83หมà¹\88à¸\9aà¸\99{{SITENAME}} ($4) บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
$2
{{PLURAL:$3|รหัสผ่านชั่วคราวนี้|รหัสผ่านชั่วคราวเหล่านี้}}จะหมดอายุใน $5 วัน
-à¸\95à¸à¸\99à¸\99ีà¹\89à¸\84ุà¸\93à¸\84วรลà¹\87à¸à¸\81à¸à¸´à¸\99à¹\81ละà¹\80ลืà¸à¸\81รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88 หาà¸\81à¸\9aุà¸\84à¸\84ลà¸à¸·à¹\88à¸\99à¸\82à¸à¸\95ัวà¹\80à¸\95ืà¸à¸\99รายละà¹\80à¸à¸µà¸¢à¸\94à¸\9aัà¸\8dà¸\8aี หรืà¸à¸\84ุà¸\93à¸\88ำรหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมà¸\82à¸à¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¹\81ลà¹\89ว à¹\81ละà¸\84ุà¸\93à¹\84มà¹\88à¸\95à¹\89à¸à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99รหัสà¸\9cà¹\88าà¸\99à¸à¸µà¸\81à¸\95à¹\88à¸à¹\84à¸\9b à¸\84ุà¸\93à¸à¸²à¸\88ละà¹\80ลยà¸\82à¹\89à¸à¸\84วามà¸\99ีà¹\89à¹\81ละà¹\83à¸\8aà¹\89รหัสà¸\9cà¹\88าà¸\99à¹\80à¸\81à¹\88าของคุณต่อไป',
-'passwordreset-emailtext-user' => 'à¸\9cูà¹\89à¹\83à¸\8aà¹\89 $1 à¸\82à¸à¸\95ัวà¹\80à¸\95ืà¸à¸\99รายละà¹\80à¸à¸µà¸¢à¸\94à¸\9aัà¸\8dà¸\8aีà¸\82à¸à¸\87à¸\84ุà¸\93à¸\9aà¸\99 {{SITENAME}} ($4) {{PLURAL:$3||}}บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
+à¸\95à¸à¸\99à¸\99ีà¹\89à¸\84ุà¸\93à¸\84วรลà¹\87à¸à¸\81à¸à¸´à¸\99à¹\81ละà¹\80ลืà¸à¸\81รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88 หาà¸\81à¸\9aุà¸\84à¸\84ลà¸à¸·à¹\88à¸\99à¸\82à¸à¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\99ีà¹\89 หรืà¸à¸\84ุà¸\93à¸\88ำรหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมà¸\82à¸à¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¹\81ลà¹\89ว à¹\81ละà¸\84ุà¸\93à¹\84มà¹\88à¸\95à¹\89à¸à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99รหัสà¸\9cà¹\88าà¸\99à¸à¸µà¸\81 à¸\84ุà¸\93à¸à¸²à¸\88ละà¹\80ลยà¸\82à¹\89à¸à¸\84วามà¸\99ีà¹\89à¹\81ละà¹\83à¸\8aà¹\89รหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมของคุณต่อไป',
+'passwordreset-emailtext-user' => 'à¸\9cูà¹\89à¹\83à¸\8aà¹\89 $1 à¸\82à¸à¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¸\82à¸à¸\87à¸\84ุà¸\93à¹\83หมà¹\88à¸\9aà¸\99{{SITENAME}} ($4) {{PLURAL:$3||}}บัญชีผู้ใช้ดังกล่าวเกี่ยวข้องกับที่อยู่อีเมลนี้:
$2
{{PLURAL:$3|รหัสผ่านชั่วคราวนี้|รหัสผ่านชั่วคราวเหล่านี้}}จะหมดอายุใน $5 วัน
-à¸\95à¸à¸\99à¸\99ีà¹\89à¸\84ุà¸\93à¸\84วรลà¹\87à¸à¸\81à¸à¸´à¸\99à¹\81ละà¹\80ลืà¸à¸\81รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88 หาà¸\81à¸\9aุà¸\84à¸\84ลà¸à¸·à¹\88à¸\99à¸\82à¸à¸\95ัวà¹\80à¸\95ืà¸à¸\99รายละà¹\80à¸à¸µà¸¢à¸\94à¸\9aัà¸\8dà¸\8aี หรืà¸à¸\84ุà¸\93à¸\88ำรหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมà¸\82à¸à¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¹\81ลà¹\89ว à¹\81ละà¸\84ุà¸\93à¹\84มà¹\88à¸\95à¹\89à¸à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99รหัสà¸\9cà¹\88าà¸\99à¸à¸µà¸\81à¸\95à¹\88à¸à¹\84à¸\9b à¸\84ุà¸\93à¸à¸²à¸\88ละà¹\80ลยà¸\82à¹\89à¸à¸\84วามà¸\99ีà¹\89à¹\81ละà¹\83à¸\8aà¹\89รหัสà¸\9cà¹\88าà¸\99à¹\80à¸\81à¹\88าของคุณต่อไป',
+à¸\95à¸à¸\99à¸\99ีà¹\89à¸\84ุà¸\93à¸\84วรลà¹\87à¸à¸\81à¸à¸´à¸\99à¹\81ละà¹\80ลืà¸à¸\81รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88 หาà¸\81à¸\9aุà¸\84à¸\84ลà¸à¸·à¹\88à¸\99à¸\82à¸à¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\99ีà¹\89 หรืà¸à¸\84ุà¸\93à¸\88ำรหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมà¸\82à¸à¸\87à¸\84ุà¸\93à¹\84à¸\94à¹\89à¹\81ลà¹\89ว à¹\81ละà¸\84ุà¸\93à¹\84มà¹\88à¸\95à¹\89à¸à¸\87à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99รหัสà¸\9cà¹\88าà¸\99à¸à¸µà¸\81 à¸\84ุà¸\93à¸à¸²à¸\88ละà¹\80ลยà¸\82à¹\89à¸à¸\84วามà¸\99ีà¹\89à¹\81ละà¹\83à¸\8aà¹\89รหัสà¸\9cà¹\88าà¸\99à¹\80à¸\94ิมของคุณต่อไป',
'passwordreset-emailelement' => 'ชื่อผู้ใช้: $1
รหัสผ่านชั่วคราว: $2',
'passwordreset-emailsent' => 'อีเมลตั้งรหัสผ่านใหม่ถูกส่งไปแล้ว',
'passwordreset-emailsent-capture' => 'อีเมลตั้งรหัสผ่านใหม่ถูกส่งไปแล้ว ซึ่งแสดงด้านล่าง',
-'passwordreset-emailerror-capture' => 'à¸à¸µà¹\80มลà¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\96ูà¸\81สรà¹\89าà¸\87à¸\82ึà¹\89à¸\99à¹\81ลà¹\89ว à¸\8bึà¹\88à¸\87à¹\81สà¸\94à¸\87à¸\82à¹\89าà¸\87ลà¹\88าà¸\87 à¹\81à¸\95à¹\88à¸\81ารสà¹\88à¸\87à¹\84à¸\9bยัà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\89มà¹\80หลว: $1',
+'passwordreset-emailerror-capture' => 'à¸à¸µà¹\80มลà¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\96ูà¸\81สรà¹\89าà¸\87à¸\82ึà¹\89à¸\99à¹\81ลà¹\89ว à¸\8bึà¹\88à¸\87à¹\81สà¸\94à¸\87à¸\94à¹\89าà¸\99ลà¹\88าà¸\87 à¹\81à¸\95à¹\88à¹\84มà¹\88สามารà¸\96สà¹\88à¸\87à¹\84à¸\9bยัà¸\87{{GENDER:$2|à¸\9cูà¹\89à¹\83à¸\8aà¹\89}}: $1',
# Special:ChangeEmail
'changeemail' => 'เปลี่ยนที่อยู่อีเมล',
'resettokens-legend' => 'ตั้งโทเค็นใหม่',
'resettokens-tokens' => 'โทเค็น:',
'resettokens-token-label' => '$1 (ค่าปัจจุบัน: $2)',
-'resettokens-watchlist-token' => 'โทเค็นการป้อนเว็บรายการเฝ้าดู',
+'resettokens-watchlist-token' => 'โทเค็นการป้อนเว็บ (Atom/RSS) ของ[[Special:Watchlist|การเปลี่ยนแปลงไปยังหน้าในรายการเฝ้าดูของคุณ]]',
'resettokens-done' => 'ตั้งโทเค็นใหม่แล้ว',
'resettokens-resetbutton' => 'ตั้งโทเค็นที่เลือกใหม่',
'loginreqlink' => 'ล็อกอิน',
'loginreqpagetext' => 'คุณต้อง$1เพื่อดูหน้าอื่น',
'accmailtitle' => 'ส่งรหัสผ่านแล้ว',
-'accmailtext' => "มีการสร้างรหัสผ่านแบบสุ่มให้กับ [[User talk:$1|$1]] โดยจัดส่งไปที่ $2
-
-สามารถเปลี่ยนรหัสผ่านของบัญชีใหม่นี้ในหน้า''[[Special:ChangePassword|เปลี่ยนรหัสผ่าน]]'' หลังล็อกอินแล้ว",
+'accmailtext' => "รหัสผ่านแบบสุ่มของ [[User talk:$1|$1]] ถูกส่งไปยัง $2 แล้ว สามารถเปลี่ยนรหัสผ่านในหน้า''[[Special:ChangePassword|เปลี่ยนรหัสผ่าน]]'' หลังล็อกอิน",
'newarticle' => '(ใหม่)',
'newarticletext' => "คุณตามลิงก์ไปยังหน้าที่ยังไม่มีในขณะนี้
ในการสร้างหน้า เริ่มพิมพ์ในกล่องด้านล่าง (ดูข้อมูลเพิ่มเติมใน[[{{MediaWiki:Helppage}}|หน้าคำอธิบาย]])
'gender-unknown' => 'ไม่ระบุ',
'gender-male' => 'ชาย',
'gender-female' => 'หญิง',
-'prefs-help-gender' => 'เป็นข้อมูลเสริม: ใช้เพื่อให้ซอฟต์แวร์แยกแยะเพศของผู้ใช้ได้ ข้อมูลนี้จะเปิดเผยต่อสาธารณะ',
+'prefs-help-gender' => 'เลือกตั้งค่านี้หรือไม่ก็ได้
+ซอฟต์แวร์ใช้ค่านี้เพื่อติดต่อคุณและกล่าวถึงคุณโดยใช้เพศทางไวยากรณ์ที่เหมาะสมเมื่อติดต่อผู้อื่น
+ข้อมูลนี้เปิดเผยต่อสาธารณะ',
'email' => 'อีเมล',
'prefs-help-realname' => 'ไม่จำเป็นต้องใช้ชื่อจริง ถ้าคุณเลือกใช้ชื่อจริง จะใช้เพื่อให้เกียรติแก่งานของคุณ',
'prefs-help-email' => 'ไม่จำเป็นต้องใส่ที่อยู่อีเมล แต่จำเป็นสำหรับการตั้งรหัสผ่านใหม่เมื่อคุณลืมรหัสผ่าน',
'userrights-no-interwiki' => 'คุณไม่ได้รับสิทธิแก้ไขสิทธิผู้ใช้บนวิกิอื่น',
'userrights-nodatabase' => 'ไม่มีฐานข้อมูล $1 อยู่ หรือฐานข้อมูลอยู่บนเครื่องอื่น',
'userrights-nologin' => 'คุณต้อง[[Special:UserLogin|ล็อกอิน]]ด้วยบัญชีผู้ดูแลระบบก่อน จึงจะกำหนดสิทธิผู้ใช้ได้',
-'userrights-notallowed' => 'à¸\9aัà¸\8dà¸\8aีà¸\82à¸à¸\87à¸\84ุà¸\93à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸à¸\99ุà¸\8dาà¸\95à¹\83หà¹\89à¹\80à¸\9eิà¹\88มหรืà¸à¸¥à¸\94สิà¸\97à¸\98ิà¸\82à¸à¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89',
+'userrights-notallowed' => 'บัญชีของคุณไม่ได้รับอนุญาตให้เพิ่มหรือลดสิทธิผู้ใช้',
'userrights-changeable-col' => 'กลุ่มที่คุณสามารถเปลี่ยนได้',
'userrights-unchangeable-col' => 'กลุ่มที่คุณไม่สามารถเปลี่ยนได้',
'right-proxyunbannable' => 'เลี่ยงการบล็อกอัตโนมัติของพร็อกซี',
'right-unblockself' => 'ปลดบล็อกตนเอง',
'right-protect' => 'เปลี่ยนระดับการล็อกและแก้ไขหน้าที่ถูกล็อก',
-'right-editprotected' => 'หน้าที่ถูกล็อกเต็มที่ (ที่ไม่ล็อกแบบสืบทอด)',
+'right-editprotected' => 'แก้ไขหน้าที่ถูกล็อกซึ่ง "{{int:protect-level-sysop}}"',
+'right-editsemiprotected' => 'แก้ไขหน้าที่ถูกล็อกซึ่ง "{{int:protect-level-autoconfirmed}}"',
'right-editinterface' => 'แก้ไขอินเตอร์เฟซผู้ใช้',
'right-editusercssjs' => 'แก้ไขไฟล์ CSS และจาวาสคริปต์ของผู้ใช้อื่น',
'right-editusercss' => 'แก้ไขไฟล์ CSS ของผู้ใช้อื่น',
'mostrevisions' => 'หน้าที่มีรุ่นมากที่สุด',
'prefixindex' => 'ทุกหน้าพร้อมคำขึ้นต้น',
'prefixindex-namespace' => 'ทุกหน้าพร้อมคำขึ้นต้น (เนมสเปซ $1)',
+'prefixindex-strip' => 'ลบคำขึ้นต้นในรายการออก',
'shortpages' => 'หน้าสั้น',
'longpages' => 'หน้ายาว',
'deadendpages' => 'หน้าสุดทาง',
'linksearch-ok' => 'ค้นหา',
'linksearch-text' => 'สามารถใช้ตัวแทนเช่น "*.wikipedia.org" ได้
ต้องการโดเมนระดับบนสุดเป็นอย่างน้อย เช่น "*.org"<br />
-โพรโทคอลที่รองรับ: <code>$1</code> (ค่าโดยปริยายเป็น http:// หากไม่ระบุโพรโทคอล)',
+{PLURAL:$2|โพรโทคอล}}ที่รองรับ: <code>$1</code> (ค่าโดยปริยายเป็น http:// หากไม่ระบุโพรโทคอล)',
'linksearch-line' => '$1 ถูกลิงก์จาก $2',
'linksearch-error' => 'อักขระตัวแทนอยู่ได้เฉพาะหน้าชื่อโฮสต์เท่านั้น',
'pageinfo-length' => 'ความยาวหน้า (ไบต์)',
'pageinfo-article-id' => 'หมายเลขประจำหน้า',
'pageinfo-language' => 'ภาษาเนื้อหาของหน้า',
-'pageinfo-robot-policy' => 'สà¸\96าà¸\99ะà¹\80สิรà¹\8cà¸\8aà¹\80à¸à¸\99à¸\88ิà¸\99',
+'pageinfo-robot-policy' => 'à¸\81ารà¸\97ำà¸\94ัà¸\8aà¸\99ีà¹\82à¸\94ยà¸\9aà¸à¸\95',
'pageinfo-robot-index' => 'อนุญาต',
'pageinfo-robot-noindex' => 'ไม่อนุญาต',
'pageinfo-views' => 'จำนวนการเข้าดู',
'pageinfo-redirectsto' => 'เปลี่ยนทางไปยัง',
'pageinfo-contentpage' => 'นับเป็นหน้าเนื้อหา',
'pageinfo-contentpage-yes' => 'ใช่',
+'pageinfo-protect-cascading' => 'การล็อกที่สืบทอดจากหน้านี้',
'pageinfo-protect-cascading-yes' => 'ใช่',
+'pageinfo-protect-cascading-from' => 'การล็อกที่สืบทอดมายังหน้านี้',
'pageinfo-category-info' => 'ข้อมูลหมวดหมู่',
'pageinfo-category-pages' => 'จำนวนหน้า',
'pageinfo-category-subcats' => 'จำนวนหมวดหมู่ย่อย',
'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath เส้นทางบทความ]',
'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath เส้นทางสคริปต์]',
+# Special:Redirect
+'redirect' => 'การเปลี่ยนทางตามชื่อไฟล์ รหัสประจำผู้ใช้หรือรุ่น',
+'redirect-legend' => 'การเปลี่ยนทางไปยังไฟล์หรือหน้า',
+'redirect-summary' => 'หน้าพิเศษนี้เปลี่ยนทางไปยังไฟล์ (ระบุเป็นชื่อไฟล์) หน้า (ระบุเป็นรหัสรุ่น) หรือหน้าผู้ใช้ (ระบุเป็นรหัสผู้ใช้)',
+'redirect-submit' => 'ไป',
+'redirect-lookup' => 'ค้นดู:',
+'redirect-value' => 'ค่า:',
+'redirect-user' => 'รหัสผู้ใช้',
+'redirect-revision' => 'รุ่นหน้า',
+'redirect-file' => 'ชื่อไฟล์',
+'redirect-not-exists' => 'ไม่พบค่า',
+
# Special:FileDuplicateSearch
'fileduplicatesearch' => 'ค้นหาไฟล์ที่ซ้ำซ้อน',
'fileduplicatesearch-summary' => 'ค้นหาไฟล์ที่ซ้ำกันตามค่าแฮช',
'logentry-newusers-create2' => 'บัญชีผู้ใช้ $3 ถูกสร้างขึ้นโดย $1',
'logentry-newusers-byemail' => 'บัญชีผู้ใช้ $3 ถูกสร้างขึ้นโดย $1 และส่งรหัสผ่านไปทางอีเมลแล้ว',
'logentry-newusers-autocreate' => 'บัญชีผู้ใช้ $1 ถูกสร้างขึ้นอัตโนมัติ',
+'logentry-rights-rights' => '$1 {{GENDER:$2|เปลี่ยน}}กลุ่มสมาชิกของ $3 จาก $4 เป็น $5',
+'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|เปลี่ยน}}กลุ่มสมาชิกของ $3',
+'logentry-rights-autopromote' => '$1 ได้รับการ{{GENDER:$2|เลื่อนกลุ่ม}}จาก $4 เป็น $5 อัตโนมัติ',
'rightsnone' => '(ไม่มี)',
# Feedback
'confirmemail_text' => "Pinagagawa ng {{SITENAME}} na patotohanan mo ang iyong adres ng e-liham bago gamitin ang mga kasangkapang-katangian ng e-liham. Pindutin at buhayin ang pindutan sa ibaba para makapagpadala ng isang makapagpapatotoong e-liham (kompirmasyon) patungo sa iyong adres.
Makakasama sa liham ang isang kawing na naglalaman ng kodigo;
Ikarga ang kawing sa iyong pantingin-tingin (''browser'') para mapatotohanang katanggap-tanggap ang iyong adres ng e-liham.",
-'confirmemail_pending' => 'Naipadala na sa iyong e-liham ang kodigo ng pagpapatotoo (kumpirmasyon); kung kamakailan mo lamang nilikha ang iyong kuwenta/akawnt, maaaring ibigin mong maghintay ng ilang minuto para makarating muna ito bago subuking humiling ng isang bagong kodigo.',
+'confirmemail_pending' => 'Naipadala na sa iyong e-liham ang kodigo ng pagpapatotoo (kumpirmasyon); kung kamakailan mo lamang nilikha ang iyong kuwenta, maaaring ibigin mong maghintay ng ilang minuto para makarating muna ito bago subuking humiling ng isang bagong kodigo.',
'confirmemail_send' => 'Magpadala ng isang kodigo ng pagpapatotoo (kumpirmasyon)',
'confirmemail_sent' => 'Naipadala na ang magpapatotoong e-liham (kumpirmasyon).',
'confirmemail_oncreate' => 'Nagpadala na ng isang kodigo ng pagpapatotoo (kumpirmasyon) patungo sa iyong adres ng e-liham. Hindi kailangan ang kodigong ito para makalagda, ngunit kailangan mong ibigay muna ito bago paganahin/paandarin ang anumang pang e-liham na kasangkapang-katangiang nasa loob ng wiki.',
'confirmemail_loggedin' => 'Natiyak na ngayon ang tirahan ng e-liham mo.',
'confirmemail_error' => 'May nangyaring kamalian sa pagsasagip ng iyong kumpirmasyon.',
'confirmemail_subject' => 'Kumpirmasyon/pagpapatotoong pang-adres ng e-liham ng {{SITENAME}}',
-'confirmemail_body' => 'May isa, maaaring ikaw, na mula sa adres ng IP na $1,
-ang nagtala ng isang akawnt/kuwentang "$2" na mayroong ganitong adres ng e-liham sa {{SITENAME}}.
+'confirmemail_body' => 'May isa, maaaring ikaw, na mula sa direksiyong IP na $1,
+ang nagtala ng isang kuwentang "$2" na mayroong ganitong direksiyong e-liham sa {{SITENAME}}.
-Para patotohanang ikaw nga ang may-ari ng kuwentang ito at para buhayin ang mga kasangkapang-katanginan ng e-liham sa {{SITENAME}}, buksan ang kawing na ito sa iyong pantingin-tingin (\'\'browser\'\'):
+Para patotohanang ikaw nga ang may-ari ng kuwentang ito at para buhayin ang mga kasangkapang-katanginan ng e-liham sa {{SITENAME}}, buksan ang kawing na ito sa iyong pambasa-basa (\'\'browser\'\'):
$3
-Kung *hindi* mo itinala/inirehistro ang kuwenta, sundan mo ang kawing na ito
-para kanselahin o huwag nang ituloy ang pagpapatotoo (kumpirmasyon) ng adres ng e-liham:
+Kung *hindi* mo itinala ang kuwenta, sundan mo ang kawing na ito
+para kanselahin o huwag nang ituloy ang pagpapatotoo (kumpirmasyon) ng direksiyong e-liham:
$5
-Magwawakas ang pagiging mabisa ng kodigo ng pagpapatotoong ito sa $4.',
+Magwawalang-saysay ang kodigo ng pagpapatotoong ito sa $4.',
'confirmemail_body_changed' => 'May isa, maaaring ikaw, na mula sa adres ng IP na $1,
ang nagbago ng adres ng e-liham ng akawnt na "$2" sa ganitong adres sa {{SITENAME}}.
'tog-hidepatrolled' => 'Son değişikliklerde gözden geçirilen düzenlemeleri gizle',
'tog-newpageshidepatrolled' => 'Kontrol edilmiş sayfaları yeni sayfalar listesinde gizle',
'tog-extendwatchlist' => 'İzleme listesini sadece en son değil, tüm değişiklikleri göstermek için genişlet',
-'tog-usenewrc' => 'Son değişiklikler sayfasındaki ve izleme listesindeki değişiklikleri gruplandırma (JavaScript gerektirir)',
+'tog-usenewrc' => 'Son değişiklikler sayfasındaki ve izleme listesindeki değişiklikleri gruplandırma',
'tog-numberheadings' => 'Başlıkları otomatik numaralandır',
-'tog-showtoolbar' => 'Düzenleme yaparken araç çubuğunu göster (JavaScript gerektirir)',
-'tog-editondblclick' => 'Çift tıklayarak sayfaları düzenle (JavaScript gerektirir)',
+'tog-showtoolbar' => 'Düzenleme yaparken araç çubuğunu göster',
+'tog-editondblclick' => 'Çift tıklayarak sayfaları düzenle',
'tog-editsection' => 'Bölümleri [{{int:Editsection}}] bağlantıları ile düzenlemeyi etkinleştir',
-'tog-editsectiononrightclick' => 'Bölüm başlığına sağ tıklayarak bölümleri düzenleyebilme olanağı ver (JavaScript gerektirir)',
+'tog-editsectiononrightclick' => 'Bölüm başlığına sağ tıklayarak bölümleri düzenleyebilme olanağı ver',
'tog-showtoc' => 'İçindekiler tablosunu göster (3 taneden fazla başlığı olan sayfalar için)',
'tog-rememberpassword' => 'Girişimi bu tarayıcıda hatırla (en fazla $1 {{PLURAL:$1|gün|gün}} için)',
'tog-watchcreations' => 'Açtığım sayfaları ve yüklediğim dosyaları izleme listeme ekle',
'tog-shownumberswatching' => 'İzleyen kullanıcı sayısını göster',
'tog-oldsig' => 'Mevcut imza:',
'tog-fancysig' => 'İmzaya vikimetin muamelesi yap (otomatik bir bağlantı olmadan)',
-'tog-uselivepreview' => 'Canlı ön izlemeyi kullan (JavaScript gerektirir ve özellik deneme aşamasındadır)',
+'tog-uselivepreview' => 'Canlı önizlemeyi kullan (deneysel)',
'tog-forceeditsummary' => 'Özeti boş bıraktığımda beni uyar',
'tog-watchlisthideown' => 'İzleme listemden düzenlemelerimi gizle',
'tog-watchlisthidebots' => 'İzleme listemden bot değişikliklerini gizle',
'newwindow' => '(yeni bir pencerede açılır)',
'cancel' => 'İptal',
'moredotdotdot' => 'Daha...',
-'morenotlisted' => 'Listede daha fazlası yok...',
+'morenotlisted' => 'Bu liste tam değildir.',
'mypage' => 'Sayfa',
'mytalk' => 'Mesaj',
'anontalk' => "Bu IP'nin iletileri",
# General errors
'error' => 'Hata',
'databaseerror' => 'Veritabanı hatası',
+'databaseerror-text' => 'Bir veritabanı sorgu hatası oluştu.
+Bu yazılım bir hata gösteriyor olabilir.',
+'databaseerror-textcl' => 'Bir veritabanı sorgu hatası oluştu.',
+'databaseerror-query' => 'Sorgu: $1',
+'databaseerror-function' => 'Fonksiyon: $1',
+'databaseerror-error' => 'Hata: $1',
'laggedslavemode' => 'Uyarı: Sayfa son güncellemeleri içermeyebilir.',
'readonly' => 'Veritabanı kilitlendi',
'enterlockreason' => 'Koruma için bir neden belirtin. Korumanın ne zaman kaldırılacağına dair tahmini bir tarih eklemeyi unutmayın.',
Lütfen URL\'yi not ederek bunu bir [[Special:ListUsers/sysop|hizmetliye]] iletin.',
'missingarticle-rev' => '(revizyon#: $1)',
'missingarticle-diff' => '(Fark: $1, $2)',
-'readonly_lag' => 'Yedek sunucular ana sunucu ile güncellemeye çalışırken veritabanı otomatik olarak kilitlendi.',
+'readonly_lag' => 'Yedek sunucular ana sunucu ile güncellenmeye çalışılırken veritabanı otomatik olarak kilitlendi.',
'internalerror' => 'Yazılım hatası',
'internalerror_info' => 'İç hata: $1',
'fileappenderrorread' => 'Ekleme yapılırken "$1" okunamadı.',
'fileexistserror' => '"$1" dosyasına yazılamadı: dosya zaten mevcut',
'unexpected' => 'beklenmeyen değer: "$1"="$2".',
'formerror' => 'Hata: Form gönderilemiyor',
-'badarticleerror' => 'Yapmak istediğiniz işlem geçersizdir.',
+'badarticleerror' => 'Bu işlem, bu sayfada yapılamaz.',
'cannotdelete' => '"$1" sayfa ya da dosyası silinemedi.
Başka bir kullanıcı tarafından silinmiş olabilir.',
'cannotdelete-title' => '"$1" sayfasını silemezsiniz',
'changeemail-cancel' => 'İptal',
# Special:ResetTokens
-'resettokens' => 'Belirteçleri sıfırla',
-'resettokens-text' => 'Burada hesabınızla ilişkili bazı özel verilere erişim izin belirteçleri sıfırlayabilirsiniz.
+'resettokens' => 'Anahtarları sıfırla',
+'resettokens-text' => 'Burada hesabınızla ilişkili bazı özel verilere erişim izin anahtarları sıfırlayabilirsiniz.
Siz yanlışlıkla bunları paylaştıysanız veya hesabınızda bir bozulma varsa bunu yapmalısınız.',
'resettokens-no-tokens' => 'Sıfırlamak için hiç bir belirteç bulunmuyor.',
-'resettokens-legend' => 'Belirteçleri sıfırla',
+'resettokens-legend' => 'Anahtarları sıfırla',
'resettokens-tokens' => 'Belirteçler:',
'resettokens-token-label' => '$1 (geçerli değer: $2)',
-'resettokens-watchlist-token' => 'İzleme listesi web beslemesi belirteci',
+'resettokens-watchlist-token' => '[[Special:Watchlist|İzleme listenizdeki sayfa değişiklikleri]] için web beslemeleri (Atom/RSS) anahtarı',
'resettokens-done' => 'Belirteçler sıfırlandı.',
-'resettokens-resetbutton' => 'Seçili belirteçleri sıfırla',
+'resettokens-resetbutton' => 'Seçili anahtarları sıfırla',
# Edit page toolbar
'bold_sample' => 'Kalın yazı',
'datedefault' => 'Tercih yok',
'prefs-beta' => 'Beta özellikleri',
'prefs-datetime' => 'Tarih ve saat',
-'prefs-labs' => 'Lab özellikleri',
+'prefs-labs' => 'Deneysel özellikler',
'prefs-user-pages' => 'Kullanıcı sayfaları',
'prefs-personal' => 'Kullanıcı bilgileri',
'prefs-rc' => 'Son değişiklikler',
'prefs-watchlist-days-max' => 'en fazla $1 {{PLURAL:$1|gün|gün}}',
'prefs-watchlist-edits' => 'Genişletilmiş izleme listesinde gösterilecek değişiklik sayısı:',
'prefs-watchlist-edits-max' => 'En fazla sayı: 1000',
-'prefs-watchlist-token' => 'İzleme listesi nişanı:',
+'prefs-watchlist-token' => 'İzleme listesi anahtarı:',
'prefs-misc' => 'Diğer ayarlar',
'prefs-resetpass' => 'Parolayı değiştir',
'prefs-changeemail' => "E-posta'yı değiştir",
'recentchangesdays-max' => '(en fazla $1 {{PLURAL:$1|gün|gün}})',
'recentchangescount' => 'Varsayılan olarak gösterilecek değişiklik sayısı:',
'prefs-help-recentchangescount' => 'Bu, son değişiklikleri, sayfa geçmişlerini ve günlükleri içerir.',
+'prefs-help-watchlist-token2' => 'Bu izleme listenizin gizli anahtarıdır. Anahtarı bilen herkes izleme listenizi görebilir. Bu nedenle kimseyle paylaşmayın. [[Special:ResetTokens|Bu anahtarı sıfırlamak isterseniz buraya tıklayın]].',
'savedprefs' => 'Tercihleriniz kaydedildi.',
'timezonelegend' => 'Zaman dilimi:',
'localtime' => 'Yerel saat:',
'prefs-files' => 'Dosyalar',
'prefs-custom-css' => 'Özel CSS',
'prefs-custom-js' => 'Özel JS',
-'prefs-common-css-js' => 'Tüm kaplamalar için paylaşılan CSS/JS:',
+'prefs-common-css-js' => 'Tüm temalar için paylaşılan CSS/JS:',
'prefs-reset-intro' => 'Bu sayfayı tercihlerinizi site varsayılanına döndürmek için kullanabilirsiniz. Bu geri alınamaz.',
'prefs-emailconfirm-label' => 'E-posta doğrulaması:',
'youremail' => 'E-posta:',
'badsig' => 'Geçersiz ham imza; HTML etiketlerini kontrol edin.',
'badsiglength' => 'İmzanız çok uzun.
$1 {{PLURAL:$1|karakterin|karakterin}} altında olmalı.',
-'yourgender' => 'Cinsiyet:',
-'gender-unknown' => 'Belirtilmemiş',
-'gender-male' => 'Erkek',
+'yourgender' => 'Nasıl açıklamayı tercih edersiniz?',
+'gender-unknown' => 'Söylemek istemiyorsanız',
+'gender-male' => 'Wiki düzenlemelerinde kadın olarak',
'gender-female' => 'Bayan',
-'prefs-help-gender' => 'İsteğe bağlı: Yazılım tarafından doğru cinsiyet adreslemesi için kullanılır. Bu bilgi umumi olacaktır.',
+'prefs-help-gender' => 'Bu tercih ayarı isteğe bağlıdır.
+Yazılımda söz değerlerinin başlarında bulunan cinsiyete uygun gramerler için kullanılır.
+Bu bilgiler herkes tarafından görülebilir.',
'email' => 'E-posta',
'prefs-help-realname' => '* Gerçek isim (isteğe bağlı): eğer gerçek isminizi vermeyi seçerseniz, çalışmanızı size atfederken kullanılacaktır.',
'prefs-help-email' => 'E-posta adresi isteğe bağlıdır; ancak parolanızı unutmanız durumunda parola sıfırlamak için gerekecektir.',
'prefs-i18n' => 'Uluslararasılaştırma',
'prefs-signature' => 'İmza',
'prefs-dateformat' => 'Tarih biçemi',
-'prefs-timeoffset' => 'Zaman ofseti',
+'prefs-timeoffset' => 'Saat farkı',
'prefs-advancedediting' => 'Genel seçenekler',
+'prefs-editor' => 'Editör',
+'prefs-preview' => 'Önizleme',
'prefs-advancedrc' => 'Gelişmiş seçenekler',
'prefs-advancedrendering' => 'Gelişmiş seçenekler',
'prefs-advancedsearchoptions' => 'Gelişmiş seçenekler',
'prefs-displayrc' => 'Görüntü seçenekleri',
'prefs-displaysearchoptions' => 'Görüntüleme seçenekleri',
'prefs-displaywatchlist' => 'Görüntüleme seçenekleri',
+'prefs-tokenwatchlist' => 'Anahtar',
'prefs-diffs' => 'Farklar',
# User preference: email validation using jQuery
'randompage' => 'Rastgele sayfa',
'randompage-nopages' => 'Şu {{PLURAL:$2|ad alanında|ad alanlarında}} hiç bir sayfa yok: $1.',
+# Random page in category
+'randomincategory' => 'Kategoriye göre rastgele sayfa',
+'randomincategory-selectcategory' => 'Rastgele sayfa alınacak kategori: $1 $2.',
+
# Random redirect
'randomredirect' => 'Rastgele yönlendirme',
'randomredirect-nopages' => '"$1" ad alanında hiç bir yönlendirme yok.',
'statistics-users-active-desc' => 'Son {{PLURAL:$1|gün|$1 günde}} çalışma yapan kullanıcılar',
'statistics-mostpopular' => 'En çok ziyaret edilen sayfalar',
+'pageswithprop' => 'Bir sayfa özelliğine sahip sayfalar',
+'pageswithprop-text' => 'Bu sayfa belirli bir sayfa özelliğini kullanan sayfaları listeler.',
'pageswithprop-submit' => 'Git',
'doubleredirects' => 'Çift yönlendirmeler',
'specialloguserlabel' => 'Kullanıcı:',
'speciallogtitlelabel' => 'Hedef (başlık ya da kullanıcı):',
'log' => 'Kayıtlar',
-'all-logs-page' => 'Tüm umumi kayıtlar',
+'all-logs-page' => 'Tüm ortak günlükler',
'alllogstext' => '{{SITENAME}} için mevcut tüm günlüklerin birleşik gösterimi.
Günlük tipini, kullanıcı adını (büyük-küçük harf duyarlı), ya da etkilenen sayfayı (yine büyük-küçük harf duyarlı) seçerek görünümü daraltabilirsiniz.',
'logempty' => 'Kayıtlarda eşleşen bilgi yok.',
'exif-headline' => 'Başlık',
'exif-credit' => 'Sağlayıcı',
'exif-source' => 'Kaynak',
+'exif-editstatus' => 'Görüntünün yayın durumu',
'exif-urgency' => 'Aciliyet',
'exif-fixtureidentifier' => 'Fikstür adı',
'exif-locationdest' => 'Yerin konumu',
'version-entrypoints-header-url' => 'URL',
# Special:Redirect
+'redirect' => 'Dosya, kullanıcı veya sayfa ID yönlendirme',
+'redirect-legend' => 'Bir dosya veya sayfaya yönlendirme',
+'redirect-summary' => "Bu özel sayfa sizi bir dosya (dosya adı verilen), bir sayfa (bir revizyon ID'si verilen) veya bir kullanıcı sayfasının (sayısal kullanıcı kimliği verilen) adresine yönlendirir.",
'redirect-submit' => 'Git',
'redirect-value' => 'Değer:',
'redirect-user' => 'Kullanıcı kimliği',
'redirect-file' => 'Dosya adı',
+'redirect-not-exists' => 'Değer bulunamadı',
# Special:FileDuplicateSearch
'fileduplicatesearch' => 'Benzer dosyaları ara',
# API errors
'api-error-badaccess-groups' => 'Bu wiki için dosya yüklemenize izin verilmiyor.',
-'api-error-badtoken' => 'İç hata: Bozuk simge.',
+'api-error-badtoken' => 'İç hata: Bozuk anahtar.',
'api-error-duplicate-popup-title' => 'Çift {{PLURAL:$1|dosya|dosya}}',
'api-error-empty-file' => 'Gönderdiğiniz dosya boş.',
'api-error-emptypage' => 'Yeni, boş bir sayfa oluşturmaya izin verilmez.',
* @author Reedy
* @author Wu-chinese.com
* @author Yfdyh000
+ * @author 十弌
*/
$fallback = 'zh-hans';
'tog-extendwatchlist' => '扩展监控列表,显示所有改动,而弗仅仅是最近个',
'tog-usenewrc' => '使用强化版个近段辰光个改动(JavaScript)',
'tog-numberheadings' => '标题自动编号',
-'tog-showtoolbar' => '显示编辑工具条(JavaScript)',
-'tog-editondblclick' => '双击个辰光编辑页面(JavaScript)',
+'tog-showtoolbar' => '顯示編寫傢伙欄',
+'tog-editondblclick' => '雙捺來編寫頁面',
'tog-editsection' => '允许通过点击【编辑】链接来编辑段落',
-'tog-editsectiononrightclick' => '允许右击标题编辑段落(JavaScript)',
+'tog-editsectiononrightclick' => '用右捺標題編輯段落',
'tog-showtoc' => '显示目录(针对超过三只标题个页面)',
'tog-rememberpassword' => '来许箇台电脑上记牢我个密码(可维持$1{{PLURAL:$1|日|日}})',
'tog-watchcreations' => '拿我创建个页面添加到我个监控列表里向',
# General errors
'error' => '错误',
'databaseerror' => '数据库错误',
+'databaseerror-text' => '一個數據庫討信發生。
+嘸數說明一個bug徠軟件裏向。',
+'databaseerror-textcl' => '一個數據庫討信賺爻發生。',
+'databaseerror-query' => '討信:$1',
+'databaseerror-error' => '賺爻:$1',
'laggedslavemode' => '警告: 页面可能弗包含最近个更新。',
'readonly' => '数据库锁定',
'enterlockreason' => '请输入锁定个原因,包括预计解锁个辰光',
'yourlanguage' => '语言:',
'yournick' => '绰号:',
'badsig' => '无效原始签名;检查 HTML 标签。',
+'gender-unknown' => '我弗想講',
'email' => '电子邮件',
'prefs-help-email' => '电子邮件是备选个,垃拉侬忘记密码个情况下头可以用得来重置密码。
侬也可以让别人家通过侬个用户页或者讨论页来联系侬。',
'newpageletter' => '新',
'boteditletter' => '机',
'newsectionsummary' => '/* $1 */ 新段落',
-'rc-enhanced-expand' => '显示细节(需要JavaScript支持)',
+'rc-enhanced-expand' => '展示零碎',
'rc-enhanced-hide' => '拿细节囥脱',
# Recent changes linked
# Special:SpecialPages
'specialpages' => '特殊页面',
+# Database error messages
+'dberr-info-hidden' => '(數據庫服務器連弗上)',
+
# New logging system
'revdelete-restricted' => '已将限制应用到管理员',
'revdelete-unrestricted' => '已移除对管理员个限制',
'tooltip-n-recentchanges' => '本wiki最近更改的列表',
'tooltip-n-randompage' => '载入一个随机页面',
'tooltip-n-help' => '查找帮助的地方',
-'tooltip-t-whatlinkshere' => '所有链至本页的wiki页面的列表',
+'tooltip-t-whatlinkshere' => '所有链至本页的维基页面的列表',
'tooltip-t-recentchangeslinked' => '链自本页的页面的最近更改',
'tooltip-feed-rss' => '本页面的RSS源',
'tooltip-feed-atom' => '本页面的Atom源',
$get = 0;
$time_start = $this->microtime_float();
for ( $i = 1; $i <= $iterations; $i++ ) {
- if ( !is_null( $mcc->set( "test$i", $i ) ) ) {
+ if ( $mcc->set( "test$i", $i ) ) {
$set++;
}
}
rc_this_oldid INT DEFAULT 0,
rc_last_oldid INT DEFAULT 0,
rc_type tinyint DEFAULT 0,
- rc_moved_to_ns BIT DEFAULT 0,
- rc_moved_to_title NVARCHAR(255) DEFAULT '',
rc_patrolled BIT DEFAULT 0,
rc_ip NCHAR(40) DEFAULT '',
rc_old_len INT DEFAULT 0,
rc_this_oldid NUMBER DEFAULT 0 NOT NULL,
rc_last_oldid NUMBER DEFAULT 0 NOT NULL,
rc_type CHAR(1) DEFAULT '0' NOT NULL,
- rc_moved_to_ns NUMBER DEFAULT 0 NOT NULL,
- rc_moved_to_title VARCHAR2(255),
rc_patrolled CHAR(1) DEFAULT '0' NOT NULL,
rc_ip VARCHAR2(15),
rc_old_len NUMBER,
rc_this_oldid INTEGER NOT NULL,
rc_last_oldid INTEGER NOT NULL,
rc_type SMALLINT NOT NULL DEFAULT 0,
- rc_moved_to_ns SMALLINT,
- rc_moved_to_title TEXT,
rc_patrolled SMALLINT NOT NULL DEFAULT 0,
rc_ip CIDR,
rc_old_len INTEGER,
--- /dev/null
+<?php
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Fixes all rows affected by https://bugzilla.wikimedia.org/show_bug.cgi?id=37714
+ */
+class TidyUpBug37714 extends Maintenance {
+ public function execute() {
+ // Search for all log entries which are about changing the visability of other log entries.
+ $result = wfGetDB( DB_SLAVE )->select(
+ 'logging',
+ array( 'log_id', 'log_params' ),
+ array(
+ 'log_type' => array( 'suppress', 'delete' ),
+ 'log_action' => 'event',
+ 'log_namespace' => NS_SPECIAL,
+ 'log_title' => SpecialPage::getTitleFor( 'Log' )->getText()
+ ),
+ __METHOD__
+ );
+
+ foreach ( $result as $row ) {
+ $paramLines = explode( "\n", $row->log_params );
+ $ids = explode( ',', $paramLines[0] ); // Array dereferencing is PHP >= 5.4 :(
+ $result = wfGetDB( DB_SLAVE )->select( // Work out what log entries were changed here.
+ 'logging',
+ 'log_type',
+ array( 'log_id' => $ids ),
+ __METHOD__,
+ 'DISTINCT'
+ );
+ if ( $result->numRows() === 1 ) {
+ // If there's only one type, the target title can be set to include it.
+ $logTitle = SpecialPage::getTitleFor( 'Log', $result->current()->log_type )->getText();
+ $this->output( 'Set log_title to "' . $logTitle . '" for log entry ' . $row->log_id . ".\n" );
+ wfGetDB( DB_MASTER )->update(
+ 'logging',
+ array( 'log_title' => $logTitle ),
+ array( 'log_id' => $row->log_id ),
+ __METHOD__
+ );
+ wfWaitForSlaves();
+ }
+ }
+ }
+}
+
+$maintClass = 'TidyUpBug37714';
+require_once RUN_MAINTENANCE_IF_MAIN;
$updates[] = 'noschema';
}
$updates[] = 'stats';
-
- if ( !$this->hasOption( 'nopurge' ) ) {
- $updates[] = 'purge';
- }
}
$updater = DatabaseUpdater::newForDb( $db, $shared, $this );
$containers.hide();
hookCallback();
} else {
- $.when( $containers.stop( true, true ).fadeOut() ).then( hookCallback );
+ $containers.stop( true, true ).fadeOut().promise().done( hookCallback );
}
} else {
- $.when( $containers.stop( true, true ).fadeIn() ).then( hookCallback );
+ $containers.stop( true, true ).fadeIn().promise().done( hookCallback );
}
} else if ( !options.plainMode && ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) ) {
$containers.hide();
hookCallback();
} else {
- $.when( $containers.stop( true, true ).slideUp() ).then( hookCallback );
+ $containers.stop( true, true ).slideUp().promise().done( hookCallback );
}
} else {
- $.when( $containers.stop( true, true ).slideDown() ).then( hookCallback );
+ $containers.stop( true, true ).slideDown().promise().done( hookCallback );
}
} else {
$collapsibleContent.hide();
hookCallback();
} else {
- $.when( $collapsibleContent.slideUp() ).then( hookCallback );
+ $collapsibleContent.slideUp().promise().done( hookCallback );
}
} else {
- $.when( $collapsibleContent.slideDown() ).then( hookCallback );
+ $collapsibleContent.slideDown().promise().done( hookCallback );
}
// Otherwise assume this is a customcollapse with a remote toggle
hookCallback();
} else {
if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
- $.when( $collapsible.fadeOut() ).then( hookCallback );
+ $collapsible.fadeOut().promise().done( hookCallback );
} else {
- $.when( $collapsible.slideUp() ).then( hookCallback );
+ $collapsible.slideUp().promise().done( hookCallback );
}
}
} else {
if ( $collapsible.is( 'tr' ) || $collapsible.is( 'td' ) || $collapsible.is( 'th' ) ) {
- $.when( $collapsible.fadeIn() ).then( hookCallback );
+ $collapsible.fadeIn().promise().done( hookCallback );
} else {
- $.when( $collapsible.slideDown() ).then( hookCallback );
+ $collapsible.slideDown().promise().done( hookCallback );
}
}
}
preventDefault = false;
switch ( key ) {
- case 40: // Arrow down
+ // Arrow down
+ case 40:
if ( wasVisible ) {
$.suggestions.highlight( context, 'next', true );
context.data.selectedWithMouse = false;
}
preventDefault = true;
break;
- case 38: // Arrow up
+ // Arrow up
+ case 38:
if ( wasVisible ) {
$.suggestions.highlight( context, 'prev', true );
context.data.selectedWithMouse = false;
}
preventDefault = wasVisible;
break;
- case 27: // Escape
+ // Escape
+ case 27:
context.data.$container.hide();
$.suggestions.restore( context );
$.suggestions.cancel( context );
context.data.$textbox.trigger( 'change' );
preventDefault = wasVisible;
break;
- case 13: // Enter
+ // Enter
+ case 13:
context.data.$container.hide();
preventDefault = wasVisible;
selected = context.data.$container.find( '.suggestions-result-current' );
switch ( context.data.keypressed ) {
// This preventDefault logic is duplicated from
// $.suggestions.keypress(), which sucks
- case 40: // Arrow down
+ // Arrow down
+ case 40:
e.preventDefault();
e.stopImmediatePropagation();
break;
- case 38: // Arrow up
- case 27: // Escape
- case 13: // Enter
+ // Arrow up, Escape and Enter
+ case 38:
+ case 27:
+ case 13:
if ( context.data.$container.is( ':visible' ) ) {
e.preventDefault();
e.stopImmediatePropagation();
isCategory: function ( title, ok, err ) {
var d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
apiPromise = this.get( {
prop: 'categoryinfo',
getCategoriesByPrefix: function ( prefix, ok, err ) {
var d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
// Fetch with allpages to only get categories that have a corresponding description page.
apiPromise = this.get( {
getCategories: function ( title, ok, err, async ) {
var d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
apiPromise = this.get( {
prop: 'categories',
getEditToken: function ( ok, err ) {
var d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
apiPromise = this.get( {
action: 'tokens',
parse: function ( wikitext, ok, err ) {
var d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
apiPromise = this.get( {
action: 'parse',
var params,
d = $.Deferred(),
apiPromise;
+
// Backwards compatibility (< MW 1.20)
- d.done( ok );
- d.fail( err );
+ d.done( ok ).fail( err );
params = {
action: 'watch',
* @singleton
*/
( function ( mw, $ ) {
- var callbacks, options, tokens, user;
+ var user,
+ callbacks = {},
+ // Extend the skeleton mw.user from mediawiki.js
+ // This is kind of ugly but we're stuck with this for b/c reasons
+ options = mw.user.options || new mw.Map(),
+ tokens = mw.user.tokens || new mw.Map();
/**
- * Gets the current user's groups or rights.
+ * Get the current user's groups or rights
*
* @private
* @param {string} info One of 'groups' or 'rights'
} );
}
- callbacks = {};
-
- // Extend the skeleton mw.user from mediawiki.js
- // This is kind of ugly but we're stuck with this for b/c reasons
- options = mw.user.options || new mw.Map();
- tokens = mw.user.tokens || new mw.Map();
-
mw.user = user = {
options: options,
tokens: tokens,
/**
- * Generates a random user session ID (32 alpha-numeric characters).
+ * Generate a random user session ID (32 alpha-numeric characters)
*
* This information would potentially be stored in a cookie to identify a user during a
* session or series of sessions. Its uniqueness should not be depended on.
},
/**
- * Gets the current user's database id.
+ * Get the current user's database id
*
- * Not to be confused with #id
+ * Not to be confused with #id.
*
* @return {number} Current user's id, or 0 if user is anonymous
*/
},
/**
- * Gets the current user's name.
+ * Get the current user's name
*
* @return {string|null} User name string or null if user is anonymous
*/
},
/**
- * Get date user registered, if available.
+ * Get date user registered, if available
*
* @return {Date|boolean|null} Date user registered, or false for anonymous users, or
* null when data is not available
},
/**
- * Checks if the current user is anonymous.
+ * Whether the current user is anonymous
*
* @return {boolean}
*/
},
/**
- * Gets a random ID automatically generated and stored in a session cookie.
+ * Get an automatically generated random ID (stored in a session cookie)
*
* This ID is ephemeral for everyone, staying in their browser only until they close
* their browser.
*/
sessionId: function () {
var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
- if ( typeof sessionId === 'undefined' || sessionId === null ) {
+ if ( sessionId === undefined || sessionId === null ) {
sessionId = user.generateRandomSessionId();
- $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
+ $.cookie( 'mediaWiki.user.sessionId', sessionId, { expires: null, path: '/' } );
}
return sessionId;
},
/**
- * Gets the current user's name or the session ID
+ * Get the current user's name or the session ID
*
- * Not to be confused with #getId
+ * Not to be confused with #getId.
*
* @return {string} User name or random session ID
*/
id: function () {
- var name = user.getName();
- if ( name ) {
- return name;
- }
- return user.sessionId();
+ return user.getName() || user.sessionId();
},
/**
- * Gets the user's bucket, placing them in one at random based on set odds if needed.
+ * Get the user's bucket (place them in one if not done already)
*
* mw.user.bucket( 'test', {
- * 'buckets': { 'ignored': 50, 'control': 25, 'test': 25 },
- * 'version': 1,
- * 'expires': 7
+ * buckets: { ignored: 50, control: 25, test: 25 },
+ * version: 1,
+ * expires: 7
* } );
*
* @param {string} key Name of bucket
* @param {Object} options Bucket configuration options
* @param {Object} options.buckets List of bucket-name/relative-probability pairs (required,
* must have at least one pair)
- * @param {number} options.version Version of bucket test, changing this forces rebucketing
- * (optional, default: 0)
- * @param {number} options.expires Length of time (in days) until the user gets rebucketed
- * (optional, default: 30)
- * @return {string} Bucket name - the randomly chosen key of the options.buckets object
+ * @param {number} [options.version=0] Version of bucket test, changing this forces
+ * rebucketing
+ * @param {number} [options.expires=30] Length of time (in days) until the user gets
+ * rebucketed
+ * @return {string} Bucket name - the randomly chosen key of the `options.buckets` object
*/
bucket: function ( key, options ) {
var cookie, parts, version, bucket,
cookie = $.cookie( 'mediaWiki.user.bucket:' + key );
// Bucket information is stored as 2 integers, together as version:bucket like: "1:2"
- if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) > 0 ) {
+ if ( typeof cookie === 'string' && cookie.length > 2 && cookie.indexOf( ':' ) !== -1 ) {
parts = cookie.split( ':' );
if ( parts.length > 1 && Number( parts[0] ) === options.version ) {
version = Number( parts[0] );
bucket = String( parts[1] );
}
}
+
if ( bucket === undefined ) {
if ( !$.isPlainObject( options.buckets ) ) {
- throw 'Invalid buckets error. Object expected for options.buckets.';
+ throw new Error( 'Invalid bucket. Object expected for options.buckets.' );
}
+
version = Number( options.version );
+
// Find range
range = 0;
for ( k in options.buckets ) {
range += options.buckets[k];
}
+
// Select random value within range
rand = Math.random() * range;
+
// Determine which bucket the value landed in
total = 0;
for ( k in options.buckets ) {
break;
}
}
+
$.cookie(
'mediaWiki.user.bucket:' + key,
version + ':' + bucket,
- { 'path': '/', 'expires': Number( options.expires ) }
+ { path: '/', expires: Number( options.expires ) }
);
}
+
return bucket;
},
/**
- * Gets the current user's groups.
+ * Get the current user's groups
*
* @param {Function} callback
*/
},
/**
- * Gets the current user's rights.
+ * Get the current user's rights
*
* @param {Function} callback
*/
+( function ( mw, $ ) {
-window.ProtectionForm = {
- 'existingMatch': false,
+var ProtectionForm = window.ProtectionForm = {
+ existingMatch: false,
/**
* Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
* numTypes The number of protection types
* existingMatch True if all the existing expiry times match
*/
- 'init': function( opts ) {
- if( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) )
+ init: function ( opts ) {
+ var box, boxbody, row, cell, check, label;
+
+ if ( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) ) {
return false;
+ }
- var box = document.getElementById( opts.tableId );
- if( !box )
+ box = document.getElementById( opts.tableId );
+ if ( !box ) {
return false;
+ }
- var boxbody = box.getElementsByTagName('tbody')[0];
- var row = document.createElement( 'tr' );
+ boxbody = box.getElementsByTagName( 'tbody' )[0];
+ row = document.createElement( 'tr' );
boxbody.insertBefore( row, boxbody.firstChild.nextSibling );
this.existingMatch = opts.existingMatch;
- var cell = document.createElement( 'td' );
+ cell = document.createElement( 'td' );
row.appendChild( cell );
// If there is only one protection type, there is nothing to chain
- if( opts.numTypes > 1 ) {
- var check = document.createElement( 'input' );
+ if ( opts.numTypes > 1 ) {
+ check = document.createElement( 'input' );
check.id = 'mwProtectUnchained';
check.type = 'checkbox';
cell.appendChild( check );
- addClickHandler( check, function() { ProtectionForm.onChainClick(); } );
+ window.addClickHandler( check, function () {
+ ProtectionForm.onChainClick();
+ } );
cell.appendChild( document.createTextNode( ' ' ) );
- var label = document.createElement( 'label' );
+ label = document.createElement( 'label' );
label.htmlFor = 'mwProtectUnchained';
label.appendChild( document.createTextNode( opts.labelText ) );
cell.appendChild( label );
/**
* Sets the disabled attribute on the cascade checkbox depending on the current selected levels
*/
- 'updateCascadeCheckbox': function() {
+ updateCascadeCheckbox: function () {
+ var i, lists, items, selected;
+
// For non-existent titles, there is no cascade option
- if( !document.getElementById( 'mwProtect-cascade' ) ) {
+ if ( !document.getElementById( 'mwProtect-cascade' ) ) {
return;
}
- var lists = this.getLevelSelectors();
- for( var i = 0; i < lists.length; i++ ) {
- if( lists[i].selectedIndex > -1 ) {
- var items = lists[i].getElementsByTagName( 'option' );
- var selected = items[ lists[i].selectedIndex ].value;
- if( !this.isCascadeableLevel(selected) ) {
+ lists = this.getLevelSelectors();
+ for ( i = 0; i < lists.length; i++ ) {
+ if ( lists[i].selectedIndex > -1 ) {
+ items = lists[i].getElementsByTagName( 'option' );
+ selected = items[ lists[i].selectedIndex ].value;
+ if ( !this.isCascadeableLevel( selected ) ) {
document.getElementById( 'mwProtect-cascade' ).checked = false;
document.getElementById( 'mwProtect-cascade' ).disabled = true;
return;
* @param level {String}
* @return {Boolean}
*/
- 'isCascadeableLevel': function( level ) {
+ isCascadeableLevel: function ( level ) {
var cascadeLevels, len, i;
cascadeLevels = mw.config.get( 'wgCascadeableLevels' );
*
* @param source Element Level selector that changed
*/
- 'updateLevels': function(source) {
- if( !this.isUnchained() )
+ updateLevels: function ( source ) {
+ if ( !this.isUnchained() ) {
this.setAllSelectors( source.selectedIndex );
+ }
this.updateCascadeCheckbox();
},
* @param source Element expiry input that changed
*/
- 'updateExpiry': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpiryInput(function(element) {
+ updateExpiry: function ( source ) {
+ var expiry, listId, list;
+
+ if ( !this.isUnchained() ) {
+ expiry = source.value;
+ this.forEachExpiryInput( function ( element ) {
element.value = expiry;
- });
+ } );
}
- var listId = source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
- var list = document.getElementById( listId );
- if (list && list.value != 'othertime' ) {
+ listId = source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
+ list = document.getElementById( listId );
+ if ( list && list.value !== 'othertime' ) {
if ( this.isUnchained() ) {
list.value = 'othertime';
} else {
- this.forEachExpirySelector(function(element) {
+ this.forEachExpirySelector( function ( element ) {
element.value = 'othertime';
- });
+ } );
}
}
},
*
* @param source Element expiry selector that changed
*/
- 'updateExpiryList': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpirySelector(function(element) {
+ updateExpiryList: function ( source ) {
+ var expiry;
+ if ( !this.isUnchained() ) {
+ expiry = source.value;
+ this.forEachExpirySelector( function ( element ) {
element.value = expiry;
- });
- this.forEachExpiryInput(function(element) {
+ } );
+ this.forEachExpiryInput( function ( element ) {
element.value = '';
- });
+ } );
}
},
* Update chain status and enable/disable various bits of the UI
* when the user changes the "unlock move permissions" checkbox
*/
- 'onChainClick': function() {
- if( this.isUnchained() ) {
+ onChainClick: function () {
+ if ( this.isUnchained() ) {
this.enableUnchainedInputs( true );
} else {
this.setAllSelectors( this.getMaxLevel() );
/**
* Returns true if the named attribute in all objects in the given array are matching
*/
- 'matchAttribute' : function( objects, attrName ) {
- var value = null;
+ matchAttribute: function ( objects, attrName ) {
+ var i, element, value;
// Check levels
- for ( var i = 0; i < objects.length; i++ ) {
- var element = objects[i];
- if ( value == null ) {
+ value = null;
+ for ( i = 0; i < objects.length; i++ ) {
+ element = objects[i];
+ if ( value === null ) {
value = element[attrName];
} else {
- if ( value != element[attrName] ) {
+ if ( value !== element[attrName] ) {
return false;
}
}
*
* @return boolean
*/
- 'areAllTypesMatching': function() {
+ areAllTypesMatching: function () {
return this.existingMatch
&& this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
&& this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
*
* @return bool
*/
- 'isUnchained': function() {
+ isUnchained: function () {
var element = document.getElementById( 'mwProtectUnchained' );
return element
? element.checked
/**
* Find the highest protection level in any selector
*/
- 'getMaxLevel': function() {
+ getMaxLevel: function () {
var maxIndex = -1;
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex > maxIndex) {
+ this.forEachLevelSelector( function ( element ) {
+ if ( element.selectedIndex > maxIndex ) {
maxIndex = element.selectedIndex;
}
- });
+ } );
return maxIndex;
},
*
* @param index int Protection level
*/
- 'setAllSelectors': function(index) {
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex != index) {
+ setAllSelectors: function ( index ) {
+ this.forEachLevelSelector( function ( element ) {
+ if ( element.selectedIndex !== index ) {
element.selectedIndex = index;
}
- });
+ } );
},
/**
*
* @param func callable Callback function
*/
- 'forEachLevelSelector': function(func) {
- var selectors = this.getLevelSelectors();
- for (var i = 0; i < selectors.length; i++) {
- func(selectors[i]);
+ forEachLevelSelector: function ( func ) {
+ var i, selectors;
+
+ selectors = this.getLevelSelectors();
+ for ( i = 0; i < selectors.length; i++ ) {
+ func( selectors[i] );
}
},
*
* @return Array
*/
- 'getLevelSelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtect-level-/)) {
+ getLevelSelectors: function () {
+ var i, ours, all, element;
+
+ all = document.getElementsByTagName( 'select' );
+ ours = [];
+ for ( i = 0; i < all.length; i++ ) {
+ element = all[i];
+ if ( element.id.match( /^mwProtect-level-/ ) ) {
ours[ours.length] = element;
}
}
*
* @param func callable Callback function
*/
- 'forEachExpiryInput': function(func) {
- var inputs = this.getExpiryInputs();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
+ forEachExpiryInput: function ( func ) {
+ var i, inputs;
+
+ inputs = this.getExpiryInputs();
+ for ( i = 0; i < inputs.length; i++ ) {
+ func( inputs[i] );
}
},
*
* @return Array
*/
- 'getExpiryInputs': function() {
- var all = document.getElementsByTagName("input");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.name.match(/^mwProtect-expiry-/)) {
+ getExpiryInputs: function () {
+ var i, all, element, ours;
+
+ all = document.getElementsByTagName( 'input' );
+ ours = [];
+ for ( i = 0; i < all.length; i++ ) {
+ element = all[i];
+ if ( element.name.match( /^mwProtect-expiry-/ ) ) {
ours[ours.length] = element;
}
}
* Apply a callback to each expiry selector list
* @param func callable Callback function
*/
- 'forEachExpirySelector': function(func) {
- var inputs = this.getExpirySelectors();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
+ forEachExpirySelector: function ( func ) {
+ var i, inputs;
+
+ inputs = this.getExpirySelectors();
+ for ( i = 0; i < inputs.length; i++ ) {
+ func( inputs[i] );
}
},
*
* @return Array
*/
- 'getExpirySelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtectExpirySelection-/)) {
+ getExpirySelectors: function () {
+ var i, all, ours, element;
+
+ all = document.getElementsByTagName( 'select' );
+ ours = [];
+ for ( i = 0; i < all.length; i++ ) {
+ element = all[i];
+ if ( element.id.match( /^mwProtectExpirySelection-/ ) ) {
ours[ours.length] = element;
}
}
*
* @param val boolean Enable?
*/
- 'enableUnchainedInputs': function(val) {
+ enableUnchainedInputs: function ( val ) {
var first = true;
- this.forEachLevelSelector(function(element) {
- if (first) {
+
+ this.forEachLevelSelector( function ( element ) {
+ if ( first ) {
first = false;
} else {
element.disabled = !val;
}
- });
+ } );
first = true;
- this.forEachExpiryInput(function(element) {
- if (first) {
+ this.forEachExpiryInput( function ( element ) {
+ if ( first ) {
first = false;
} else {
element.disabled = !val;
}
- });
+ } );
first = true;
- this.forEachExpirySelector(function(element) {
- if (first) {
+ this.forEachExpirySelector( function ( element ) {
+ if ( first ) {
first = false;
} else {
element.disabled = !val;
}
- });
+ } );
}
};
+
+}( mediaWiki, jQuery ) );
+/*jshint camelcase:false */
( function ( mw, $ ) {
-var ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
+var licenseSelectorCheck, wgUploadWarningObj, wgUploadLicenseObj, fillDestFilename,
+ ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
fileExtensions = mw.config.get( 'wgFileExtensions' );
-window.licenseSelectorCheck = function() {
- var selector = document.getElementById( "wpLicense" );
- var selection = selector.options[selector.selectedIndex].value;
- if( selector.selectedIndex > 0 ) {
- if( selection == "" ) {
+licenseSelectorCheck = window.licenseSelectorCheck = function () {
+ var selector = document.getElementById( 'wpLicense' ),
+ selection = selector.options[selector.selectedIndex].value;
+ if ( selector.selectedIndex > 0 ) {
+ if ( !selection ) {
// Option disabled, but browser is broken and doesn't respect this
selector.selectedIndex = 0;
}
function uploadSetup() {
// Disable URL box if the URL copy upload source type is not selected
- var e = document.getElementById( 'wpSourceTypeurl' );
- if( e ) {
- if( !e.checked ) {
- var ein = document.getElementById( 'wpUploadFileURL' );
- if(ein)
- ein.setAttribute( 'disabled', 'disabled' );
+ var ein,
+ selector, ua, isMacIe, i,
+ optionsTable, row, td,
+ wpLicense, wpLicenseRow, wpLicenseTbody,
+ uploadSourceIds, len, onchange,
+ e = document.getElementById( 'wpSourceTypeurl' );
+ if ( e ) {
+ if ( !e.checked ) {
+ ein = document.getElementById( 'wpUploadFileURL' );
+ if ( ein ) {
+ ein.disabled = true;
+ }
}
}
// For MSIE/Mac: non-breaking spaces cause the <option> not to render.
// But for some reason, setting the text to itself works
- var selector = document.getElementById("wpLicense");
- if (selector) {
- var ua = navigator.userAgent;
- var isMacIe = (ua.indexOf("MSIE") != -1) && (ua.indexOf("Mac") != -1);
- if (isMacIe) {
- for (var i = 0; i < selector.options.length; i++) {
+ selector = document.getElementById( 'wpLicense' );
+ if ( selector ) {
+ ua = navigator.userAgent;
+ isMacIe = ua.indexOf( 'MSIE' ) !== -1 && ua.indexOf( 'Mac' ) !== -1;
+ if ( isMacIe ) {
+ for ( i = 0; i < selector.options.length; i++ ) {
selector.options[i].text = selector.options[i].text;
}
}
if ( ajaxUploadDestCheck ) {
// Insert an event handler that fetches upload warnings when wpDestFile
// has been changed
- document.getElementById( 'wpDestFile' ).onchange = function ( e ) {
- wgUploadWarningObj.checkNow(this.value);
+ document.getElementById( 'wpDestFile' ).onchange = function () {
+ wgUploadWarningObj.checkNow( this.value );
};
// Insert a row where the warnings will be displayed just below the
// wpDestFile row
- var optionsTable = document.getElementById( 'mw-htmlform-description' ).tBodies[0];
- var row = optionsTable.insertRow( 1 );
- var td = document.createElement( 'td' );
+ optionsTable = document.getElementById( 'mw-htmlform-description' ).tBodies[0];
+ row = optionsTable.insertRow( 1 );
+ td = document.createElement( 'td' );
td.id = 'wpDestFile-warning';
td.colSpan = 2;
row.appendChild( td );
}
- var wpLicense = document.getElementById( 'wpLicense' );
+ wpLicense = document.getElementById( 'wpLicense' );
if ( mw.config.get( 'wgAjaxLicensePreview' ) && wpLicense ) {
// License selector check
wpLicense.onchange = licenseSelectorCheck;
// License selector table row
- var wpLicenseRow = wpLicense.parentNode.parentNode;
- var wpLicenseTbody = wpLicenseRow.parentNode;
+ wpLicenseRow = wpLicense.parentNode.parentNode;
+ wpLicenseTbody = wpLicenseRow.parentNode;
- var row = document.createElement( 'tr' );
- var td = document.createElement( 'td' );
+ row = document.createElement( 'tr' );
+ td = document.createElement( 'td' );
row.appendChild( td );
td = document.createElement( 'td' );
td.id = 'mw-license-preview';
// fillDestFile setup
- var i,
- uploadSourceIds = mw.config.get( 'wgUploadSourceIds' ),
- len = uploadSourceIds.length;
- for ( i = 0; i < len; i += 1 )
- document.getElementById( uploadSourceIds[i] ).onchange = function (e) {
- fillDestFilename( this.id );
- };
-};
+ uploadSourceIds = mw.config.get( 'wgUploadSourceIds' );
+ len = uploadSourceIds.length;
+ onchange = function () {
+ fillDestFilename( this.id );
+ };
+ for ( i = 0; i < len; i += 1 ) {
+ document.getElementById( uploadSourceIds[i] ).onchange = onchange;
+ }
+}
+wgUploadWarningObj = window.wgUploadWarningObj = {
+ responseCache: { '' : ' ' },
+ nameToCheck: '',
+ typing: false,
+ delay: 500, // ms
+ timeoutID: false,
-window.wgUploadWarningObj = {
- 'responseCache' : { '' : ' ' },
- 'nameToCheck' : '',
- 'typing': false,
- 'delay': 500, // ms
- 'timeoutID': false,
+ keypress: function () {
+ var cached, destFile, warningElt;
- 'keypress': function () {
- if ( !ajaxUploadDestCheck ) return;
+ if ( !ajaxUploadDestCheck ) {
+ return;
+ }
// Find file to upload
- var destFile = document.getElementById('wpDestFile');
- var warningElt = document.getElementById( 'wpDestFile-warning' );
- if ( !destFile || !warningElt ) return ;
+ destFile = document.getElementById( 'wpDestFile' );
+ warningElt = document.getElementById( 'wpDestFile-warning' );
+ if ( !destFile || !warningElt ) {
+ return;
+ }
- this.nameToCheck = destFile.value ;
+ this.nameToCheck = destFile.value;
// Clear timer
if ( this.timeoutID ) {
- window.clearTimeout( this.timeoutID );
+ clearTimeout( this.timeoutID );
}
// Check response cache
- for (cached in this.responseCache) {
- if (this.nameToCheck == cached) {
+ for ( cached in this.responseCache ) {
+ if ( this.nameToCheck === cached ) {
this.setWarning(this.responseCache[this.nameToCheck]);
return;
}
}
- this.timeoutID = window.setTimeout( 'wgUploadWarningObj.timeout()', this.delay );
+ this.timeoutID = setTimeout( function () {
+ wgUploadWarningObj.timeout();
+ }, this.delay );
},
- 'checkNow': function (fname) {
- if ( !ajaxUploadDestCheck ) return;
+ checkNow: function ( fname ) {
+ if ( !ajaxUploadDestCheck ) {
+ return;
+ }
if ( this.timeoutID ) {
- window.clearTimeout( this.timeoutID );
+ clearTimeout( this.timeoutID );
}
this.nameToCheck = fname;
this.timeout();
},
- 'timeout' : function() {
- if ( !ajaxUploadDestCheck || this.nameToCheck === '' ) return;
- injectSpinner( document.getElementById( 'wpDestFile' ), 'destcheck' );
+ timeout: function () {
+ if ( !ajaxUploadDestCheck || this.nameToCheck === '' ) {
+ return;
+ }
+ window.injectSpinner( document.getElementById( 'wpDestFile' ), 'destcheck' );
var uploadWarningObj = this;
- ( new mw.Api ).get( {
+ ( new mw.Api() ).get( {
action: 'query',
titles: ( new mw.Title( this.nameToCheck, mw.config.get( 'wgNamespaceIds' ).file ) ).getPrefixedText(),
prop: 'imageinfo',
} );
},
- 'processResult' : function ( result, fileName ) {
- removeSpinner( 'destcheck' );
+ processResult: function ( result, fileName ) {
+ window.removeSpinner( 'destcheck' );
this.setWarning( result.html );
this.responseCache[fileName] = result.html;
},
- 'setWarning' : function (warning) {
- var warningElt = document.getElementById( 'wpDestFile-warning' );
- var ackElt = document.getElementsByName( 'wpDestFileWarningAck' );
+ setWarning: function ( warning ) {
+ var warningElt = document.getElementById( 'wpDestFile-warning' ),
+ ackElt = document.getElementsByName( 'wpDestFileWarningAck' );
this.setInnerHTML(warningElt, warning);
// Set a value in the form indicating that the warning is acknowledged and
// doesn't need to be redisplayed post-upload
- if ( warning == '' ) {
+ if ( !warning ) {
ackElt[0].value = '';
} else {
ackElt[0].value = '1';
}
},
- 'setInnerHTML' : function (element, text) {
+ setInnerHTML: function ( element, text ) {
// Check for no change to avoid flicker in IE 7
- if (element.innerHTML != text) {
+ if ( element.innerHTML !== text ) {
element.innerHTML = text;
}
}
};
-window.fillDestFilename = function(id) {
+fillDestFilename = window.fillDestFilename = function ( id ) {
+ var e, path, slash, backslash, fname,
+ found, ext, i,
+ destFile;
if ( !mw.config.get( 'wgUploadAutoFill' ) ) {
return;
}
- if (!document.getElementById) {
+ if ( !document.getElementById ) {
return;
}
// Remove any previously flagged errors
- var e = document.getElementById( 'mw-upload-permitted' );
- if( e ) e.className = '';
+ e = document.getElementById( 'mw-upload-permitted' );
+ if ( e ) {
+ e.className = '';
+ }
- var e = document.getElementById( 'mw-upload-prohibited' );
- if( e ) e.className = '';
+ e = document.getElementById( 'mw-upload-prohibited' );
+ if ( e ) {
+ e.className = '';
+ }
- var path = document.getElementById(id).value;
+ path = document.getElementById( id ).value;
// Find trailing part
- var slash = path.lastIndexOf('/');
- var backslash = path.lastIndexOf('\\');
- var fname;
- if (slash == -1 && backslash == -1) {
+ slash = path.lastIndexOf( '/' );
+ backslash = path.lastIndexOf( '\\' );
+ if ( slash === -1 && backslash === -1 ) {
fname = path;
- } else if (slash > backslash) {
- fname = path.substring(slash+1, 10000);
+ } else if ( slash > backslash ) {
+ fname = path.substring( slash + 1, 10000 );
} else {
- fname = path.substring(backslash+1, 10000);
+ fname = path.substring( backslash + 1, 10000 );
}
// Clear the filename if it does not have a valid extension.
// URLs are less likely to have a useful extension, so don't include them in the
// extension check.
if ( mw.config.get( 'wgStrictFileExtensions' ) && fileExtensions && id !== 'wpUploadFileURL' ) {
- var found = false;
+ found = false;
if ( fname.lastIndexOf( '.' ) !== -1 ) {
- var ext = fname.substr( fname.lastIndexOf( '.' ) + 1 );
- for ( var i = 0; i < fileExtensions.length; i += 1 ) {
+ ext = fname.substr( fname.lastIndexOf( '.' ) + 1 );
+ for ( i = 0; i < fileExtensions.length; i += 1 ) {
if ( fileExtensions[i].toLowerCase() === ext.toLowerCase() ) {
found = true;
break;
}
}
}
- if( !found ) {
+ if ( !found ) {
// Not a valid extension
// Clear the upload and set mw-upload-permitted to error
- document.getElementById(id).value = '';
- var e = document.getElementById( 'mw-upload-permitted' );
- if( e ) e.className = 'error';
+ document.getElementById( id ).value = '';
+ e = document.getElementById( 'mw-upload-permitted' );
+ if ( e ) {
+ e.className = 'error';
+ }
- var e = document.getElementById( 'mw-upload-prohibited' );
- if( e ) e.className = 'error';
+ e = document.getElementById( 'mw-upload-prohibited' );
+ if ( e ) {
+ e.className = 'error';
+ }
// Clear wpDestFile as well
- var e = document.getElementById( 'wpDestFile' );
- if( e ) e.value = '';
+ e = document.getElementById( 'wpDestFile' );
+ if ( e ) {
+ e.value = '';
+ }
return false;
}
}
// Output result
- var destFile = document.getElementById( 'wpDestFile' );
+ destFile = document.getElementById( 'wpDestFile' );
if ( destFile ) {
// Call decodeURIComponent function to remove possible URL-encoded characters
// from the file name (bug 30390). Especially likely with upload-form-url.
// decodeURIComponent can throw an exception in input is invalid utf-8
try {
destFile.value = decodeURIComponent( fname );
- } catch ( e ) {
+ } catch ( err ) {
destFile.value = fname;
}
wgUploadWarningObj.checkNow( fname );
}
};
-window.toggleFilenameFiller = function() {
- if(!document.getElementById) return;
- var upfield = document.getElementById('wpUploadFile');
- var destName = document.getElementById('wpDestFile').value;
- wgUploadAutoFill = ( destName == '' || destName == ' ' );
+window.toggleFilenameFiller = function () {
+ if ( !document.getElementById ) {
+ return;
+ }
+ var destName = document.getElementById( 'wpDestFile' ).value;
+ mw.config.set( 'wgUploadAutoFill', !destName );
};
-window.wgUploadLicenseObj = {
+wgUploadLicenseObj = window.wgUploadLicenseObj = {
- 'responseCache' : { '' : '' },
+ responseCache: { '' : '' },
- 'fetchPreview': function( license ) {
- if ( !mw.config.get( 'wgAjaxLicensePreview' ) ) return;
- for (cached in this.responseCache) {
- if (cached == license) {
+ fetchPreview: function ( license ) {
+ var cached, title;
+ if ( !mw.config.get( 'wgAjaxLicensePreview' ) ) {
+ return;
+ }
+ for ( cached in this.responseCache ) {
+ if ( cached === license ) {
this.showPreview( this.responseCache[license] );
return;
}
}
- injectSpinner( document.getElementById( 'wpLicense' ), 'license' );
+ window.injectSpinner( document.getElementById( 'wpLicense' ), 'license' );
- var title = document.getElementById('wpDestFile').value;
- if ( !title ) title = 'File:Sample.jpg';
+ title = document.getElementById( 'wpDestFile' ).value;
+ if ( !title ) {
+ title = 'File:Sample.jpg';
+ }
- ( new mw.Api ).get( {
+ ( new mw.Api() ).get( {
action: 'parse',
text: '{{' + license + '}}',
title: title,
} );
},
- 'processResult' : function( result, license ) {
- removeSpinner( 'license' );
- this.responseCache[license] = result['parse']['text']['*'];
+ processResult: function ( result, license ) {
+ window.removeSpinner( 'license' );
+ this.responseCache[license] = result.parse.text['*'];
this.showPreview( this.responseCache[license] );
},
- 'showPreview' : function( preview ) {
+ showPreview: function ( preview ) {
var previewPanel = document.getElementById( 'mw-license-preview' );
- if( previewPanel.innerHTML != preview )
+ if ( previewPanel.innerHTML !== preview ) {
previewPanel.innerHTML = preview;
+ }
}
};
* the provided code.
*
* @since 1.21
+ * @deprecated since 1.22 Use setExpectedException
*
* @param callable $code
* @param string $expected
array( $PASS, 'Some ASCII' ),
array( $PASS, "Euro sign €" ),
- # First possible sequences
+ // First possible sequences
array( $PASS, "\x00" ),
array( $PASS, "\xc2\x80" ),
array( $PASS, "\xe0\xa0\x80" ),
array( $PASS, "\xf0\x90\x80\x80" ),
- array( $PASS, "\xf8\x88\x80\x80\x80" ),
- array( $PASS, "\xfc\x84\x80\x80\x80\x80" ),
+ array( $FAIL, "\xf8\x88\x80\x80\x80" ),
+ array( $FAIL, "\xfc\x84\x80\x80\x80\x80" ),
- # Last possible sequence
+ // Last possible sequence
array( $PASS, "\x7f" ),
array( $PASS, "\xdf\xbf" ),
array( $PASS, "\xef\xbf\xbf" ),
- array( $PASS, "\xf7\xbf\xbf\xbf" ),
- array( $PASS, "\xfb\xbf\xbf\xbf\xbf" ),
+ array( $FAIL, "\xf7\xbf\xbf\xbf" ), // U+1FFFFF
+ array( $FAIL, "\xfb\xbf\xbf\xbf\xbf" ),
array( $FAIL, "\xfd\xbf\xbf\xbf\xbf\xbf" ),
- # boundaries:
+ // Boundaries
array( $PASS, "\xed\x9f\xbf" ),
array( $PASS, "\xee\x80\x80" ),
array( $PASS, "\xef\xbf\xbd" ),
- array( $PASS, "\xf4\x8f\xbf\xbf" ),
- array( $PASS, "\xf4\x90\x80\x80" ),
+ array( $PASS, "\xf2\x80\x80\x80" ),
+ array( $PASS, "\xf3\xbf\xbf\xbf" ), // U+FFFFF
+ array( $PASS, "\xf4\x80\x80\x80" ), // U+100000
+ array( $PASS, "\xf4\x8f\xbf\xbf" ), // U+10FFFF
+ array( $FAIL, "\xf4\x90\x80\x80" ), // U+110000
- # Malformed
+ // Malformed
array( $FAIL, "\x80" ),
- array( $FAIL, "\xBF" ),
+ array( $FAIL, "\xbf" ),
array( $FAIL, "\x80\xbf" ),
array( $FAIL, "\x80\xbf\x80" ),
array( $FAIL, "\x80\xbf\x80\xbf" ),
array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf" ),
array( $FAIL, "\x80\xbf\x80\xbf\x80\xbf\x80" ),
- # last byte missing
+ // Last byte missing
array( $FAIL, "\xc0" ),
array( $FAIL, "\xe0\x80" ),
array( $FAIL, "\xf0\x80\x80" ),
array( $FAIL, "\xfb\xbf\xbf\xbf" ),
array( $FAIL, "\xfd\xbf\xbf\xbf\xbf" ),
- # impossible bytes
+ // Extra continuation byte
+ array( $FAIL, "e\xaf" ),
+ array( $FAIL, "\xc3\x89\xaf" ),
+ array( $FAIL, "\xef\xbc\xa5\xaf" ),
+ array( $FAIL, "\xf0\x9d\x99\xb4\xaf" ),
+
+ // Impossible bytes
array( $FAIL, "\xfe" ),
array( $FAIL, "\xff" ),
array( $FAIL, "\xfe\xfe\xff\xff" ),
- /*
- # The PHP implementation does not handle characters
- # being represented in a form which is too long :(
-
- # overlong sequences
+ // Overlong sequences
array( $FAIL, "\xc0\xaf" ),
+ array( $FAIL, "\xc1\xaf" ),
array( $FAIL, "\xe0\x80\xaf" ),
array( $FAIL, "\xf0\x80\x80\xaf" ),
array( $FAIL, "\xf8\x80\x80\x80\xaf" ),
array( $FAIL, "\xfc\x80\x80\x80\x80\xaf" ),
- # Maximum overlong sequences
+ // Maximum overlong sequences
array( $FAIL, "\xc1\xbf" ),
array( $FAIL, "\xe0\x9f\xbf" ),
- array( $FAIL, "\xf0\x8F\xbf\xbf" ),
+ array( $FAIL, "\xf0\x8f\xbf\xbf" ),
array( $FAIL, "\xf8\x87\xbf\xbf" ),
array( $FAIL, "\xfc\x83\xbf\xbf\xbf\xbf" ),
- */
- # non characters
+ // Surrogates
+ array( $PASS, "\xed\x9f\xbf" ), // U+D799
+ array( $PASS, "\xee\x80\x80" ), // U+E000
+ array( $FAIL, "\xed\xa0\x80" ), // U+D800
+ array( $FAIL, "\xed\xaf\xbf" ), // U+DBFF
+ array( $FAIL, "\xed\xb0\x80" ), // U+DC00
+ array( $FAIL, "\xed\xbf\xbf" ), // U+DFFF
+ array( $FAIL, "\xed\xa0\x80\xed\xb0\x80" ), // U+D800 U+DC00
+
+ // Noncharacters
array( $PASS, "\xef\xbf\xbe" ),
array( $PASS, "\xef\xbf\xbf" ),
);
$quote = '';
} elseif ( $this->db->getType() === 'mysql' ) {
$quote = '`';
+ } elseif ( $this->db->getType() === 'oracle' ) {
+ $quote = '/*Q*/';
} else {
$quote = '"';
}
if ( $database !== null ) {
- $database = $quote . $database . $quote . '.';
+ if ( $this->db->getType() === 'oracle' ) {
+ $database = $quote . $database . '.';
+ } else {
+ $database = $quote . $database . $quote . '.';
+ }
}
if ( $prefix === null ) {
$prefix = $this->dbPrefix();
}
- return $database . $quote . $prefix . $table . $quote;
+ if ( $this->db->getType() === 'oracle' ) {
+ return strtoupper($database . $quote . $prefix . $table);
+ } else {
+ return $database . $quote . $prefix . $table . $quote;
+ }
}
function testTableNameLocal() {
if ( $gzipped_contents === false ) {
$this->fail( "Could not get contents of $fname" );
}
- // We resort to use gzinflate instead of gzdecode, as gzdecode
- // need not be available
- $contents = gzinflate( substr( $gzipped_contents, 10, -8 ) );
- $this->assertEquals( strlen( $contents ),
- file_put_contents( $fname, $contents ), "# bytes written" );
+
+ $contents = gzdecode( $gzipped_contents );
+
+ $this->assertEquals(
+ strlen( $contents ),
+ file_put_contents( $fname, $contents ),
+ '# bytes written'
+ );
}
/**
$redirectedLocation = false;
if ( !$isTemp ) {
// Check for file redirect
- if ( $isOld ) {
- // Since redirects are associated with pages, not versions of files,
- // we look for the most current version to see if its a redirect.
- $possibleRedirFile = RepoGroup::singleton()->getLocalRepo()->findFile( $img->getName() );
- } else {
- $possibleRedirFile = RepoGroup::singleton()->getLocalRepo()->findFile( $fileName );
- }
- if ( $possibleRedirFile && !is_null( $possibleRedirFile->getRedirected() ) ) {
- $redirTarget = $possibleRedirFile->getName();
+ // Since redirects are associated with pages, not versions of files,
+ // we look for the most current version to see if its a redirect.
+ $possRedirFile = RepoGroup::singleton()->getLocalRepo()->findFile( $img->getName() );
+ if ( $possRedirFile && !is_null( $possRedirFile->getRedirected() ) ) {
+ $redirTarget = $possRedirFile->getName();
$targetFile = wfLocalFile( Title::makeTitleSafe( NS_FILE, $redirTarget ) );
if ( $targetFile->exists() ) {
$newThumbName = $targetFile->thumbName( $params );
if ( $isOld ) {
- $newThumbUrl = $targetFile->getArchiveThumbUrl( $bits[0] . '!' . $targetFile->getName(), $newThumbName );
+ $newThumbUrl = $targetFile->getArchiveThumbUrl(
+ $bits[0] . '!' . $targetFile->getName(), $newThumbName );
} else {
$newThumbUrl = $targetFile->getThumbUrl( $newThumbName );
}