'GenericArrayObject' => __DIR__ . '/includes/libs/GenericArrayObject.php',
'GetConfiguration' => __DIR__ . '/maintenance/getConfiguration.php',
'GetLagTimes' => __DIR__ . '/maintenance/getLagTimes.php',
- 'GetSlaveServer' => __DIR__ . '/maintenance/getSlaveServer.php',
+ 'GetSlaveServer' => __DIR__ . '/maintenance/getReplicaServer.php',
'GetTextMaint' => __DIR__ . '/maintenance/getText.php',
'GitInfo' => __DIR__ . '/includes/GitInfo.php',
'GlobalDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
+++ /dev/null
-<!DOCTYPE html>
-<html lang="en" dir="ltr">
-<head>
- <meta charset="utf-8">
- <link rel="stylesheet" href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.css">
- <link rel="stylesheet" media="print" href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.print.css">
-</head>
-<body>
-
-<p>This show various styles for our diff action. Style sheet: <code><a href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.css">resources/src/mediawiki.action/mediawiki.action.history.diff.css</a></code>.</p>
-<p>This file might help us fix our diff colors which have been a recurring issues among the community for a loooong time.</p>
-<p>Try it out in print mode, too. Style sheet: <code><a href="../../resources/src/mediawiki.action/mediawiki.action.history.diff.print.css">resources/src/mediawiki.action/mediawiki.action.history.diff.print.css</a></code>.</p>
-
-<p>Practical example copied from MediaWiki's HTML output:</p>
-
-<table class="diff diff-contentalign-left">
- <colgroup><col class="diff-marker">
- <col class="diff-content">
- <col class="diff-marker">
- <col class="diff-content">
- </colgroup>
-<tbody>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Lorem ipsum dolor sit amet<del class="diffchange diffchange-inline">, consectetur adipisicing elit</del>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"></td>
- <td colspan="2" class="diff-empty"> </td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
- <td colspan="2" class="diff-empty"> </td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
-</tr>
-<tr>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
- <td class="diff-marker"> </td>
- <td class="diff-context"></td>
-</tr>
-<tr>
- <td class="diff-marker">−</td>
- <td class="diff-deletedline"><div>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim<del class="diffchange diffchange-inline"> id est laborum</del>.</div></td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Excepteur sint occaecat cupidatat non proident, sunt<ins class="diffchange diffchange-inline"> reprehenderit in voluptate</ins> in culpa qui officia deserunt mollit anim.</div></td>
-</tr>
-<tr>
- <td colspan="2" class="diff-empty"> </td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"></td>
-</tr>
-<tr>
- <td colspan="2" class="diff-empty"> </td>
- <td class="diff-marker">+</td>
- <td class="diff-addedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
-</tr>
-</tbody></table>
-
-<p>Below are some basic lines being applied one or two classes. Mainly for debugging purposes.</p>
-
-<table class="diff">
- <tr><th>Diff</th></tr>
-
- <tr><td class="diff-addedline"><code>diff-addedline</code>: added line</td></tr>
- <tr><td class="diff-deletedline"><code>diff-deletedline</code>: deleted line</td></tr>
- <tr><td class="diff-context"><code>diff-context</code>: context</td></tr>
-
- <tr><th>Same as above with a <code><ins></code> or <code><del></code> child element having the <code>diffchange</code> class:</th></tr>
-
- <tr><td class="diffchange">Diffchange</td></tr>
- <tr><td class="diff-addedline"><ins class="diffchange">Added line + diffchange</ins></td></tr>
- <tr><td class="diff-deletedline"><del class="diffchange">Deleted line + diffchange</del></td></tr>
-</table>
-
-</body>
-</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="../../resources/src/mediawiki/mediawiki.diff.styles.css">
+ <link rel="stylesheet" media="print" href="../../resources/src/mediawiki/mediawiki.diff.styles.print.css">
+</head>
+<body>
+
+<p>This show various styles for our diff action. Style sheet: <code><a href="../../resources/src/mediawiki/mediawiki.diff.styles.css">resources/src/mediawiki/mediawiki.diff.styles.css</a></code>.</p>
+<p>This file might help us fix our diff colors which have been a recurring issues among the community for a loooong time.</p>
+<p>Try it out in print mode, too. Style sheet: <code><a href="../../resources/src/mediawiki/mediawiki.diff.styles.print.css">resources/src/mediawiki/mediawiki.diff.styles.print.css</a></code>.</p>
+
+<p>Practical example copied from MediaWiki's HTML output:</p>
+
+<table class="diff diff-contentalign-left">
+ <colgroup><col class="diff-marker">
+ <col class="diff-content">
+ <col class="diff-marker">
+ <col class="diff-content">
+ </colgroup>
+<tbody>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Lorem ipsum dolor sit amet<del class="diffchange diffchange-inline">, consectetur adipisicing elit</del>, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div></td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"></td>
+ <td colspan="2" class="diff-empty"> </td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
+ <td colspan="2" class="diff-empty"> </td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"><div>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div></td>
+</tr>
+<tr>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+ <td class="diff-marker"> </td>
+ <td class="diff-context"></td>
+</tr>
+<tr>
+ <td class="diff-marker">−</td>
+ <td class="diff-deletedline"><div>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim<del class="diffchange diffchange-inline"> id est laborum</del>.</div></td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Excepteur sint occaecat cupidatat non proident, sunt<ins class="diffchange diffchange-inline"> reprehenderit in voluptate</ins> in culpa qui officia deserunt mollit anim.</div></td>
+</tr>
+<tr>
+ <td colspan="2" class="diff-empty"> </td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"></td>
+</tr>
+<tr>
+ <td colspan="2" class="diff-empty"> </td>
+ <td class="diff-marker">+</td>
+ <td class="diff-addedline"><div>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></td>
+</tr>
+</tbody></table>
+
+<p>Below are some basic lines being applied one or two classes. Mainly for debugging purposes.</p>
+
+<table class="diff">
+ <tr><th>Diff</th></tr>
+
+ <tr><td class="diff-addedline"><code>diff-addedline</code>: added line</td></tr>
+ <tr><td class="diff-deletedline"><code>diff-deletedline</code>: deleted line</td></tr>
+ <tr><td class="diff-context"><code>diff-context</code>: context</td></tr>
+
+ <tr><th>Same as above with a <code><ins></code> or <code><del></code> child element having the <code>diffchange</code> class:</th></tr>
+
+ <tr><td class="diffchange">Diffchange</td></tr>
+ <tr><td class="diff-addedline"><ins class="diffchange">Added line + diffchange</ins></td></tr>
+ <tr><td class="diff-deletedline"><del class="diffchange">Deleted line + diffchange</del></td></tr>
+</table>
+
+</body>
+</html>
$this->mReason = $options['reason'];
$this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] );
- $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $options['expiry'] );
+ $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $options['expiry'] );
# Boolean settings
$this->mAuto = (bool)$options['auto'];
* @return Block|null
*/
public static function newFromID( $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->selectRow(
'ipblocks',
self::selectFields(),
* @return bool Whether a relevant block was found
*/
protected function newLoad( $vagueTarget = null ) {
- $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_REPLICA );
if ( $this->type !== null ) {
$conds = [
# range. We know that all blocks must be smaller than $wgBlockCIDRLimit,
# so we can improve performance by filtering on a LIKE clause
$chunk = self::getIpFragment( $start );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$like = $dbr->buildLike( $chunk, $dbr->anyString() );
# Fairly hard to make a malicious SQL statement out of hex characters,
$this->mParentBlockId = $row->ipb_parent_block_id;
// I wish I didn't have to do this
- $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $row->ipb_expiry );
+ $this->mExpiry = wfGetDB( DB_REPLICA )->decodeExpiry( $row->ipb_expiry );
$this->isHardblock( !$row->ipb_anon_only );
$this->isAutoblocking( $row->ipb_enable_autoblock );
*/
protected function getDatabaseArray( $db = null ) {
if ( !$db ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$expiry = $db->encodeExpiry( $this->mExpiry );
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$options = [ 'ORDER BY' => 'rc_timestamp DESC' ];
$conds = [ 'rc_user_text' => (string)$block->getTarget() ];
* @param array $ipChain List of IPs (strings), usually retrieved from the
* X-Forwarded-For header of the request
* @param bool $isAnon Exclude anonymous-only blocks if false
- * @param bool $fromMaster Whether to query the master or slave database
+ * @param bool $fromMaster Whether to query the master or replica DB
* @return array Array of Blocks
* @since 1.22
*/
if ( $fromMaster ) {
$db = wfGetDB( DB_MASTER );
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$conds = $db->makeList( $conds, LIST_OR );
if ( !$isAnon ) {
return true;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'category',
[ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
*/
public function getMembers( $limit = false, $offset = '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [ 'cl_to' => $this->getName(), 'cl_from = page_id' ];
$options = [ 'ORDER BY' => 'cl_sortkey' ];
/** @var string "AND" or "OR" */
protected $mode;
- /** @var IDatabase Read-DB slave */
+ /** @var IDatabase Read-DB replica DB */
protected $dbr;
/**
* @return array Array of page_ids (those given to seed() that match the conditions)
*/
public function run() {
- $this->dbr = wfGetDB( DB_SLAVE );
+ $this->dbr = wfGetDB( DB_REPLICA );
while ( count( $this->next ) > 0 ) {
$this->scanNextLayer();
}
}
function doCategoryQuery() {
- $dbr = wfGetDB( DB_SLAVE, 'category' );
+ $dbr = wfGetDB( DB_REPLICA, 'category' );
$this->nextPage = [
'page' => null,
* - password: DB password
* - type: DB type
*
- * - load: Ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0.
+ * - load: Ratio of DB_REPLICA load, must be >=0, the sum of all loads must be >0.
* If this is zero for any given server, no normal query traffic will be
* sent to it. It will be excluded from lag checks in maintenance scripts.
* The only way it can receive traffic is if groupLoads is used.
* - DBO_COMPRESS -- uses internal compression in database connections,
* if available
*
- * - max lag: (optional) Maximum replication lag before a slave will taken out of rotation
+ * - max lag: (optional) Maximum replication lag before a replica DB goes out of rotation
* - is static: (optional) Set to true if the dataset is static and no replication is used.
* - cliMode: (optional) Connection handles will not assume that requests are short-lived
* nor that INSERT..SELECT can be rewritten into a buffered SELECT and INSERT.
* perhaps in some command-line scripts).
*
* The first server listed in this array (with key 0) will be the master. The
- * rest of the servers will be slaves. To prevent writes to your slaves due to
+ * rest of the servers will be replica DBs. To prevent writes to your replica DBs due to
* accidental misconfiguration or MediaWiki bugs, set read_only=1 on all your
- * slaves in my.cnf. You can set read_only mode at runtime using:
+ * replica DBs in my.cnf. You can set read_only mode at runtime using:
*
* @code
* SET @@read_only=1;
* @endcode
*
- * Since the effect of writing to a slave is so damaging and difficult to clean
+ * Since the effect of writing to a replica DB is so damaging and difficult to clean
* up, we at Wikimedia set read_only=1 in my.cnf on all our DB servers, even
* our masters, and then set read_only=0 on masters at runtime.
*/
'class' => 'SqlBagOStuff',
'args' => [ [ 'slaveOnly' => false ] ]
],
- 'loggroup' => 'SQLBagOStuff'
+ 'loggroup' => 'SQLBagOStuff',
+ 'reportDupes' => false
],
'apc' => [ 'class' => 'APCBagOStuff', 'reportDupes' => false ],
$wgSquidMaxage = 18000;
/**
- * Cache timeout for the CDN when DB slave lag is high
+ * Cache timeout for the CDN when DB replica DB lag is high
* @see $wgSquidMaxage
* @since 1.27
*/
* If set, any SquidPurge call on a URL or URLs will send a second purge no less than
* this many seconds later via the job queue. This requires delayed job support.
* This should be safely higher than the 'max lag' value in $wgLBFactoryConf, so that
- * slave lag does not cause page to be stuck in stales states in CDN.
+ * replica DB lag does not cause page to be stuck in stales states in CDN.
*
* This also fixes race conditions in two-tiered CDN setups (e.g. cdn2 => cdn1 => MediaWiki).
* If a purge for a URL reaches cdn2 before cdn1 and a request reaches cdn2 for that URL,
*/
$wgStatsdMetricPrefix = 'MediaWiki';
+/**
+ * Sampling rate for statsd metrics as an associative array of patterns and rates.
+ * Patterns are Unix shell patterns (e.g. 'MediaWiki.api.*').
+ * Rates are sampling probabilities (e.g. 0.1 means 1 in 10 events are sampled).
+ * @since 1.28
+ */
+$wgStatsdSamplingRates = [];
+
/**
* InfoAction retrieves a list of transclusion links (both to and from).
* This number puts a limit on that query in the case of highly transcluded
$wgJobBackoffThrottling = [];
/**
- * Make job runners commit changes for slave-lag prone jobs one job at a time.
- * This is useful if there are many job workers that race on slave lag checks.
+ * Make job runners commit changes for replica DB-lag prone jobs one job at a time.
+ * This is useful if there are many job workers that race on replica DB lag checks.
* If set, jobs taking this many seconds of DB write time have serialized commits.
*
* Note that affected jobs may have worse lock contention. Also, if they affect
$wgAPIMaxUncachedDiffs = 1;
/**
- * Maximum amount of DB lag on a majority of DB slaves to tolerate
+ * Maximum amount of DB lag on a majority of DB replica DBs to tolerate
* before forcing bots to retry any write requests via API errors.
* This should be lower than the 'max lag' value in $wgLBFactoryConf.
*/
* Valid database indexes
* Operation-based indexes
*/
-define( 'DB_SLAVE', -1 ); # Read from the slave (or only server)
+define( 'DB_REPLICA', -1 ); # Read from a replica (or only server)
define( 'DB_MASTER', -2 ); # Write to master (or only server)
/**@}*/
# Obsolete aliases
+define( 'DB_SLAVE', -1 );
define( 'DB_READ', -1 );
define( 'DB_WRITE', -2 );
* @return bool|stdClass
*/
protected function getLastDelete() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$data = $dbr->selectRow(
[ 'logging', 'user' ],
[
$statsdPort = isset( $statsdServer[1] ) ? $statsdServer[1] : 8125;
$statsdSender = new SocketSender( $statsdHost, $statsdPort );
$statsdClient = new SamplingStatsdClient( $statsdSender, true, false );
+ $statsdClient->setSamplingRates( $config->get( 'StatsdSamplingRates' ) );
$statsdClient->send( $context->getStats()->getBuffer() );
} catch ( Exception $ex ) {
MWExceptionHandler::logException( $ex );
* Check if the site is in read-only mode and return the message if so
*
* This checks wfConfiguredReadOnlyReason() and the main load balancer
- * for slave lag. This may result in DB_SLAVE connection being made.
+ * for replica DB lag. This may result in DB connection being made.
*
* @return string|bool String when in read-only mode; false otherwise
*/
* Get a Database object.
*
* @param int $db Index of the connection to get. May be DB_MASTER for the
- * master (for write queries), DB_SLAVE for potentially lagged read
+ * master (for write queries), DB_REPLICA for potentially lagged read
* queries, or an integer >= 0 for a particular server.
*
* @param string|string[] $groups Query groups. An array of group names that this query
*
* @param string|bool $wiki The wiki ID, or false for the current wiki
*
- * Note: multiple calls to wfGetDB(DB_SLAVE) during the course of one request
+ * Note: multiple calls to wfGetDB(DB_REPLICA) during the course of one request
* will always return the same object, unless the underlying connection or load
* balancer is manually destroyed.
*
}
/**
- * Waits for the slaves to catch up to the master position
+ * Waits for the replica DBs to catch up to the master position
*
* Use this when updating very large numbers of rows, as in maintenance scripts,
- * to avoid causing too much lag. Of course, this is a no-op if there are no slaves.
+ * to avoid causing too much lag. Of course, this is a no-op if there are no replica DBs.
*
* By default this waits on the main DB cluster of the current wiki.
* If $cluster is set to "*" it will wait on all DB clusters, including
if ( isset( self::$blobCache[$this->mOldId] ) ) {
$obj = self::$blobCache[$this->mOldId];
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'text',
[ 'old_flags', 'old_text' ],
* @return string|bool
*/
function getText() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'cur', [ 'cur_text' ], [ 'cur_id' => $this->mCurId ] );
if ( !$row ) {
return false;
* @return array Array to be passed to Database::buildLike() or false on error
*/
public static function makeLikeArray( $filterEntry, $protocol = 'http://' ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$target = $protocol . $filterEntry;
$bits = wfParseUrl( $target );
return null;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Up to the value of $wgShowRollbackEditCount revisions are counted
$res = $dbr->select(
$request->response()->setCookie( 'UseCDNCache', 'false', $expires, $options );
}
- // Avoid letting a few seconds of slave lag cause a month of stale data. This logic is
+ // Avoid letting a few seconds of replica DB lag cause a month of stale data. This logic is
// also intimately related to the value of $wgCdnReboundPurgeDelay.
- if ( $factory->laggedSlaveUsed() ) {
+ if ( $factory->laggedReplicaUsed() ) {
$maxAge = $config->get( 'CdnMaxageLagged' );
$context->getOutput()->lowerCdnMaxage( $maxAge );
$request->response()->header( "X-Database-Lagged: true" );
*/
class MergeHistory {
- /** @const int Maximum number of revisions that can be merged at once (avoid too much slave lag) */
+ /** @const int Maximum number of revisions that can be merged at once */
const REVISION_LIMIT = 5000;
/** @var Title Page from which history will be merged */
$lb->setArray( $arr );
# Fetch existence plus the hiddencat property
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = array_merge(
LinkCache::getSelectFields(),
[ 'page_namespace', 'page_title', 'pp_value' ]
// Hook that allows last minute changes to the output page, e.g.
// adding of CSS or Javascript by extensions.
Hooks::run( 'BeforePageDisplay', [ &$this, &$sk ] );
- $this->getSkin()->setupSkinUserCss( $this );
try {
$sk->outputPage();
}
/**
- * Show a warning about slave lag
+ * Show a warning about replica DB lag
*
* If the lag is higher than $wgSlaveLagCritical seconds,
* then the warning is a bit more obvious. If the lag is
'user.styles',
'user.cssprefs',
] );
+ $this->getSkin()->setupSkinUserCss( $this );
// Prepare exempt modules for buildExemptModules()
$exemptGroups = [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ];
}
if ( $queryIDs ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select(
'page_props',
[
}
if ( $queryIDs != [] ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select(
'page_props',
[
* @return bool
*/
private function checkIfSent() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$sent = $dbr->selectField(
'updatelog', '1', [ 'ul_key' => $this->key ], __METHOD__ );
return $sent !== false;
*/
private function getOrCreatePingbackId() {
if ( !$this->id ) {
- $id = wfGetDB( DB_SLAVE )->selectField(
+ $id = wfGetDB( DB_REPLICA )->selectField(
'updatelog', 'ul_value', [ 'ul_key' => 'PingBack' ] );
if ( $id == false ) {
* Get extra parameters for the query string when redirecting after
* successful save.
*
- * @return array()
+ * @return array
*/
public function getExtraSuccessRedirectParameters() {
return [];
$t = Title::newFromText( $search, $ns );
$prefix = $t ? $t->getDBkey() : '';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'page',
[ 'page_id', 'page_namespace', 'page_title' ],
[
* @todo document
*/
class Revision implements IDBAccessObject {
+ /** @var int|null */
protected $mId;
-
- /**
- * @var int|null
- */
+ /** @var int|null */
protected $mPage;
+ /** @var string */
protected $mUserText;
+ /** @var string */
protected $mOrigUserText;
+ /** @var int */
protected $mUser;
+ /** @var bool */
protected $mMinorEdit;
+ /** @var string */
protected $mTimestamp;
+ /** @var int */
protected $mDeleted;
+ /** @var int */
protected $mSize;
+ /** @var string */
protected $mSha1;
+ /** @var int */
protected $mParentId;
+ /** @var string */
protected $mComment;
+ /** @var string */
protected $mText;
+ /** @var int */
protected $mTextId;
+ /** @var int */
+ protected $mUnpatrolled;
- /**
- * @var stdClass|null
- */
+ /** @var stdClass|null */
protected $mTextRow;
- /**
- * @var null|Title
- */
+ /** @var null|Title */
protected $mTitle;
+ /** @var bool */
protected $mCurrent;
+ /** @var string */
protected $mContentModel;
+ /** @var string */
protected $mContentFormat;
- /**
- * @var Content|null|bool
- */
+ /** @var Content|null|bool */
protected $mContent;
-
- /**
- * @var null|ContentHandler
- */
+ /** @var null|ContentHandler */
protected $mContentHandler;
- /**
- * @var int
- */
+ /** @var int */
protected $mQueryFlags = 0;
+ /** @var bool Used for cached values to reload user text and rev_deleted */
+ protected $mRefreshMutableFields = false;
+ /** @var string Wiki ID; false means the current wiki */
+ protected $mWiki = false;
// Revision deletion constants
const DELETED_TEXT = 1;
} else {
// Use a join to get the latest revision
$conds[] = 'rev_id=page_latest';
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
return self::loadFromConds( $db, $conds, $flags );
}
}
} else {
// Use a join to get the latest revision
$conds[] = 'rev_id = page_latest';
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
return self::loadFromConds( $db, $conds, $flags );
}
}
* Given a set of conditions, fetch a revision
*
* This method is used then a revision ID is qualified and
- * will incorporate some basic slave/master fallback logic
+ * will incorporate some basic replica DB/master fallback logic
*
* @param array $conditions
* @param int $flags (optional)
* @return Revision|null
*/
private static function newFromConds( $conditions, $flags = 0 ) {
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$rev = self::loadFromConds( $db, $conditions, $flags );
// Make sure new pending/committed revision are visibile later on
*/
private static function loadFromConds( $db, $conditions, $flags = 0 ) {
$row = self::fetchFromConds( $db, $conditions, $flags );
+ if ( $row ) {
+ $rev = new Revision( $row );
+ $rev->mWiki = $db->getWikiID();
- return $row ? new Revision( $row ) : null;
+ return $rev;
+ }
+
+ return null;
}
/**
*/
public static function fetchRevision( LinkTarget $title ) {
$row = self::fetchFromConds(
- wfGetDB( DB_SLAVE ),
+ wfGetDB( DB_REPLICA ),
[
'rev_id=page_latest',
'page_namespace' => $title->getNamespace(),
}
// rev_id is defined as NOT NULL, but this revision may not yet have been inserted.
if ( $this->mId !== null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_REPLICA, [], $this->mWiki );
$row = $dbr->selectRow(
[ 'page', 'revision' ],
self::selectPageFields(),
- [ 'page_id=rev_page',
- 'rev_id' => $this->mId ],
- __METHOD__ );
+ [ 'page_id=rev_page', 'rev_id' => $this->mId ],
+ __METHOD__
+ );
if ( $row ) {
+ // @TODO: better foreign title handling
$this->mTitle = Title::newFromRow( $row );
}
}
- if ( !$this->mTitle && $this->mPage !== null && $this->mPage > 0 ) {
- $this->mTitle = Title::newFromID( $this->mPage );
+ if ( $this->mWiki === false || $this->mWiki === wfWikiID() ) {
+ // Loading by ID is best, though not possible for foreign titles
+ if ( !$this->mTitle && $this->mPage !== null && $this->mPage > 0 ) {
+ $this->mTitle = Title::newFromID( $this->mPage );
+ }
}
return $this->mTitle;
* @return string
*/
public function getUserText( $audience = self::FOR_PUBLIC, User $user = null ) {
+ $this->loadMutableFields();
+
if ( $audience == self::FOR_PUBLIC && $this->isDeleted( self::DELETED_USER ) ) {
return '';
} elseif ( $audience == self::FOR_THIS_USER && !$this->userCan( self::DELETED_USER, $user ) ) {
* @return RecentChange|null
*/
public function getRecentChange( $flags = 0 ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
list( $dbType, ) = DBAccessObjectUtils::getDBOptions( $flags );
* @return bool
*/
public function isDeleted( $field ) {
- return ( $this->mDeleted & $field ) == $field;
+ if ( $this->isCurrent() && $field === self::DELETED_TEXT ) {
+ // Current revisions of pages cannot have the content hidden. Skipping this
+ // check is very useful for Parser as it fetches templates using newKnownCurrent().
+ // Calling getVisibility() in that case triggers a verification database query.
+ return false; // no need to check
+ }
+
+ return ( $this->getVisibility() & $field ) == $field;
}
/**
* @return int
*/
public function getVisibility() {
+ $this->loadMutableFields();
+
return (int)$this->mDeleted;
}
}
if ( !$row ) {
- // Text data is immutable; check slaves first.
- $dbr = wfGetDB( DB_SLAVE );
+ // Text data is immutable; check replica DBs first.
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'text',
[ 'old_text', 'old_flags' ],
[ 'old_id' => $textId ],
__METHOD__ );
}
- // Fallback to the master in case of slave lag. Also use FOR UPDATE if it was
+ // Fallback to the master in case of replica DB lag. Also use FOR UPDATE if it was
// used to fetch this revision to avoid missing the row due to REPEATABLE-READ.
$forUpdate = ( $this->mQueryFlags & self::READ_LOCKING == self::READ_LOCKING );
if ( !$row && ( $forUpdate || wfGetLB()->getServerCount() > 1 ) ) {
wfDebugLog( 'Revision', "No blob for text row '$textId' (revision {$this->getId()})." );
}
- # No negative caching -- negative hits on text rows may be due to corrupted slave servers
+ # No negative caching -- negative hits on text rows may be due to corrupted replica DB servers
if ( $wgRevisionCacheExpiry && $text !== false ) {
$processCache->set( $key, $text );
$cache->set( $key, $text, $wgRevisionCacheExpiry );
* @return bool
*/
public function userCan( $field, User $user = null ) {
- return self::userCanBitfield( $this->mDeleted, $field, $user );
+ return self::userCanBitfield( $this->getVisibility(), $field, $user );
}
/**
static function getTimestampFromId( $title, $id, $flags = 0 ) {
$db = ( $flags & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
// Casting fix for databases that can't take '' for rev_id
if ( $id == '' ) {
$id = 0;
}
return true;
}
+
+ /**
+ * Load a revision based on a known page ID and current revision ID from the DB
+ *
+ * This method allows for the use of caching, though accessing anything that normally
+ * requires permission checks (aside from the text) will trigger a small DB lookup.
+ * The title will also be lazy loaded, though setTitle() can be used to preload it.
+ *
+ * @param IDatabase $db
+ * @param int $pageId Page ID
+ * @param int $revId Known current revision of this page
+ * @return Revision|bool Returns false if missing
+ * @since 1.28
+ */
+ public static function newKnownCurrent( IDatabase $db, $pageId, $revId ) {
+ $cache = ObjectCache::getMainWANInstance();
+ return $cache->getWithSetCallback(
+ // Page/rev IDs passed in from DB to reflect history merges
+ $cache->makeGlobalKey( 'revision', $db->getWikiID(), $pageId, $revId ),
+ $cache::TTL_WEEK,
+ function ( $curValue, &$ttl, array &$setOpts ) use ( $db, $pageId, $revId ) {
+ $setOpts += Database::getCacheSetOptions( $db );
+
+ $rev = Revision::loadFromPageId( $db, $pageId, $revId );
+ // Reflect revision deletion and user renames
+ if ( $rev ) {
+ $rev->mTitle = null; // mutable; lazy-load
+ $rev->mRefreshMutableFields = true;
+ }
+
+ return $rev ?: false; // don't cache negatives
+ }
+ );
+ }
+
+ /**
+ * For cached revisions, make sure the user name and rev_deleted is up-to-date
+ */
+ private function loadMutableFields() {
+ if ( !$this->mRefreshMutableFields ) {
+ return; // not needed
+ }
+
+ $this->mRefreshMutableFields = false;
+ $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_REPLICA, [], $this->mWiki );
+ $row = $dbr->selectRow(
+ [ 'revision', 'user' ],
+ [ 'rev_deleted', 'user_name' ],
+ [ 'rev_id' => $this->mId, 'user_id = rev_user' ],
+ __METHOD__
+ );
+ if ( $row ) { // update values
+ $this->mDeleted = (int)$row->rev_deleted;
+ $this->mUserText = $row->user_name;
+ }
+ }
}
*/
public function reset() {
if ( !$this->res ) {
- $this->res = $this->doQuery( wfGetDB( DB_SLAVE ) );
+ $this->res = $this->doQuery( wfGetDB( DB_REPLICA ) );
} else {
$this->res->rewind();
}
# Update schema
$u = new SiteStatsUpdate( 0, 0, 0 );
$u->doUpdate();
- self::$row = self::doLoad( wfGetDB( DB_SLAVE ) );
+ self::$row = self::doLoad( wfGetDB( DB_REPLICA ) );
}
self::$loaded = true;
static function loadAndLazyInit() {
global $wgMiserMode;
- wfDebug( __METHOD__ . ": reading site_stats from slave\n" );
- $row = self::doLoad( wfGetDB( DB_SLAVE ) );
+ wfDebug( __METHOD__ . ": reading site_stats from replica DB\n" );
+ $row = self::doLoad( wfGetDB( DB_REPLICA ) );
if ( !self::isSane( $row ) ) {
// Might have just been initialized during this request? Underflow?
- wfDebug( __METHOD__ . ": site_stats damaged or missing on slave\n" );
+ wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
$row = self::doLoad( wfGetDB( DB_MASTER ) );
}
// clean schema with mwdumper.
wfDebug( __METHOD__ . ": initializing damaged or missing site_stats\n" );
- SiteStatsInit::doAllAndCommit( wfGetDB( DB_SLAVE ) );
+ SiteStatsInit::doAllAndCommit( wfGetDB( DB_REPLICA ) );
$row = self::doLoad( wfGetDB( DB_MASTER ) );
}
wfMemcKey( 'SiteStats', 'groupcounts', $group ),
$cache::TTL_HOUR,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
*/
static function pagesInNs( $ns ) {
if ( !isset( self::$pageCount[$ns] ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
self::$pageCount[$ns] = (int)$dbr->selectField(
'page',
'COUNT(*)',
} elseif ( $database ) {
$this->db = wfGetDB( DB_MASTER );
} else {
- $this->db = wfGetDB( DB_SLAVE, 'vslow' );
+ $this->db = wfGetDB( DB_REPLICA, 'vslow' );
}
}
* @return Title|null The new object, or null on an error
*/
public static function newFromID( $id, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow(
'page',
self::getSelectFields(),
if ( !count( $ids ) ) {
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'page',
* @return Title|null An object representing the article, or null if no such article was found
*/
public static function nameOf( $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$s = $dbr->selectRow(
'page',
* @param string $action Action that permission needs to be checked for
* @param User $user User to check
* @param string $rigor One of (quick,full,secure)
- * - quick : does cheap permission checks from slaves (usable for GUI creation)
- * - full : does cheap and expensive checks possibly from a slave
+ * - quick : does cheap permission checks from replica DBs (usable for GUI creation)
+ * - full : does cheap and expensive checks possibly from a replica DB
* - secure : does cheap and expensive checks, using the master as needed
* @param array $ignoreErrors Array of Strings Set this to a list of message keys
* whose corresponding errors may be ignored.
* @param string $action Action that permission needs to be checked for
* @param User $user User to check
* @param string $rigor One of (quick,full,secure)
- * - quick : does cheap permission checks from slaves (usable for GUI creation)
- * - full : does cheap and expensive checks possibly from a slave
+ * - quick : does cheap permission checks from replica DBs (usable for GUI creation)
+ * - full : does cheap and expensive checks possibly from a replica DB
* - secure : does cheap and expensive checks, using the master as needed
* @param bool $short Set this to true to stop after the first permission error.
* @return array Array of arrays of the arguments to wfMessage to explain permissions problems.
}
if ( $this->mTitleProtection === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'protected_titles',
[
return [ $this->mHasCascadingRestrictions, $pagerestrictions ];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->getNamespace() == NS_FILE ) {
$tables = [ 'imagelinks', 'page_restrictions' ];
* restrictions from page table (pre 1.10)
*/
public function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$restrictionTypes = $this->getRestrictionTypes();
*/
public function loadRestrictions( $oldFashionedRestrictions = null ) {
if ( !$this->mRestrictionsLoaded ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->exists() ) {
$res = $dbr->select(
'page_restrictions',
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds['page_namespace'] = $this->getNamespace();
$conds[] = 'page_title ' . $dbr->buildLike( $this->getDBkey() . '/', $dbr->anyString() );
$options = [];
if ( $this->getNamespace() < 0 ) {
$n = 0;
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$n = $dbr->selectField( 'archive', 'COUNT(*)',
[ 'ar_namespace' => $this->getNamespace(), 'ar_title' => $this->getDBkey() ],
if ( $this->getNamespace() < 0 ) {
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$deleted = (bool)$dbr->selectField( 'archive', '1',
[ 'ar_namespace' => $this->getNamespace(), 'ar_title' => $this->getDBkey() ],
__METHOD__
if ( count( $options ) > 0 ) {
$db = wfGetDB( DB_MASTER );
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$res = $db->select(
return [];
}
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$blNamespace = "{$prefix}_namespace";
$blTitle = "{$prefix}_title";
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'pagelinks' ],
[ 'pl_namespace', 'pl_title' ],
return $data;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'categorylinks',
* @return int|bool Old revision ID, or false if none exists
*/
public function getPreviousRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$revId = $db->selectField( 'revision', 'rev_id',
[
'rev_page' => $this->getArticleID( $flags ),
* @return int|bool Next revision ID, or false if none exists
*/
public function getNextRevisionID( $revId, $flags = 0 ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$revId = $db->selectField( 'revision', 'rev_id',
[
'rev_page' => $this->getArticleID( $flags ),
public function getFirstRevision( $flags = 0 ) {
$pageId = $this->getArticleID( $flags );
if ( $pageId ) {
- $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow( 'revision', Revision::selectFields(),
[ 'rev_page' => $pageId ],
__METHOD__,
* @return bool
*/
public function isNewPage() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return (bool)$dbr->selectField( 'page', 'page_is_new', $this->pageCond(), __METHOD__ );
}
}
if ( $this->mIsBigDeletion === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$revCount = $dbr->selectRowCount(
'revision',
}
if ( $this->mEstimateRevisions === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mEstimateRevisions = $dbr->estimateRowCount( 'revision', '*',
[ 'rev_page' => $this->getArticleID() ], __METHOD__ );
}
if ( !$old || !$new ) {
return 0; // nothing to compare
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [
'rev_page' => $this->getArticleID(),
'rev_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
}
return $authors;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'revision', 'DISTINCT rev_user_text',
[
'rev_page' => $this->getArticleID(),
*/
public function getTouched( $db = null ) {
if ( $db === null ) {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$touched = $db->selectField( 'page', 'page_touched', $this->pageCond(), __METHOD__ );
return $touched;
public function getRedirectsHere( $ns = null ) {
$redirs = [];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$where = [
'rd_namespace' => $this->getNamespace(),
'rd_title' => $this->getDBkey(),
* @throws MWException
*/
private function getConnection() {
- return $this->loadBalancer->getConnection( DB_SLAVE, [ 'watchlist' ] );
+ return $this->loadBalancer->getConnection( DB_REPLICA, [ 'watchlist' ] );
}
/**
}
/**
- * @param int $slaveOrMaster DB_MASTER or DB_SLAVE
+ * @param int $dbIndex DB_MASTER or DB_REPLICA
*
* @return DatabaseBase
* @throws MWException
*/
- private function getConnection( $slaveOrMaster ) {
- return $this->loadBalancer->getConnection( $slaveOrMaster, [ 'watchlist' ] );
+ private function getConnection( $dbIndex ) {
+ return $this->loadBalancer->getConnection( $dbIndex, [ 'watchlist' ] );
}
/**
* @return int
*/
public function countWatchedItems( User $user ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$return = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
* @return int
*/
public function countWatchers( LinkTarget $target ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$return = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
* @throws MWException
*/
public function countVisitingWatchers( LinkTarget $target, $threshold ) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$visitingWatchers = (int)$dbr->selectField(
'watchlist',
'COUNT(*)',
public function countWatchersMultiple( array $targets, array $options = [] ) {
$dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
if ( array_key_exists( 'minimumWatchers', $options ) ) {
$dbOptions['HAVING'] = 'COUNT(*) >= ' . (int)$options['minimumWatchers'];
array $targetsWithVisitThresholds,
$minimumWatchers = null
) {
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$conds = $this->getVisitingWatchersCondition( $dbr, $targetsWithVisitThresholds );
return false;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$row = $dbr->selectRow(
'watchlist',
'wl_notificationtimestamp',
"wl_title {$options['sort']}"
];
}
- $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_SLAVE );
+ $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
$res = $db->select(
'watchlist',
return $timestamps;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$lb = new LinkBatch( $targetsToLoad );
$res = $dbr->select(
$queryOptions['LIMIT'] = $unreadLimit;
}
- $dbr = $this->getConnection( DB_SLAVE );
+ $dbr = $this->getConnection( DB_REPLICA );
$rowCount = $dbr->selectRowCount(
'watchlist',
'1',
return new FakeResultWrapper( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $direction === self::DIR_PREV ) {
list( $dirs, $oper ) = [ "ASC", ">=" ];
$title = $page->getTitle();
$id = $title->getArticleID();
- $dbr = wfGetDB( DB_SLAVE );
- $dbrWatchlist = wfGetDB( DB_SLAVE, 'watchlist' );
+ $dbr = wfGetDB( DB_REPLICA );
+ $dbrWatchlist = wfGetDB( DB_REPLICA, 'watchlist' );
$setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
public function onSubmit( $data ) {
$this->useTransactionalTimeLimit();
- $source = $this->page->getFile()->getArchiveVirtualUrl(
- $this->getRequest()->getText( 'oldimage' )
- );
+ $old = $this->getRequest()->getText( 'oldimage' );
+ $localFile = $this->page->getFile();
+ $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old );
+
+ $source = $localFile->getArchiveVirtualUrl( $old );
$comment = $data['comment'];
+ if ( $localFile->getSha1() === $oldFile->getSha1() ) {
+ return Status::newFatal( 'filerevert-identical' );
+ }
+
// TODO: Preserve file properties from database instead of reloading from file
- return $this->page->getFile()->upload(
+ return $localFile->upload(
$source,
$comment,
$comment,
}
/**
- * Gets a default slave database connection object
+ * Gets a default replica DB connection object
* @return DatabaseBase
*/
protected function getDB() {
if ( !isset( $this->mSlaveDB ) ) {
- $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
+ $this->mSlaveDB = wfGetDB( DB_REPLICA, 'api' );
}
return $this->mSlaveDB;
* @param array $params
* @param bool|string $load Whether load the object's state from the database:
* - false: don't load (if the pageid is given, it will still be loaded)
- * - 'fromdb': load from a slave database
+ * - 'fromdb': load from a replica DB
* - 'fromdbmaster': load from the master database
* @return WikiPage
*/
}
}
- // If a majority of slaves are too lagged then disallow writes
- $slaveCount = wfGetLB()->getServerCount() - 1;
- if ( $numLagged >= ceil( $slaveCount / 2 ) ) {
+ // If a majority of replica DBs are too lagged then disallow writes
+ $replicaCount = wfGetLB()->getServerCount() - 1;
+ if ( $numLagged >= ceil( $replicaCount / 2 ) ) {
$laggedServers = implode( ', ', $laggedServers );
wfDebugLog(
'api-readonly',
$this->fld_patrolled = isset( $prop['patrolled'] );
$this->fld_tags = isset( $prop['tags'] );
- // Most of this code will use the 'contributions' group DB, which can map to slaves
+ // Most of this code will use the 'contributions' group DB, which can map to replica DBs
// with extra user based indexes or partioning by user. The additional metadata
- // queries should use a regular slave since the lookup pattern is not all by user.
- $dbSecondary = $this->getDB(); // any random slave
+ // queries should use a regular replica DB since the lookup pattern is not all by user.
+ $dbSecondary = $this->getDB(); // any random replica DB
// TODO: if the query is going only against the revision table, should this be done?
- $this->selectNamedDB( 'contributions', DB_SLAVE, 'contributions' );
+ $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
$this->idMode = false;
if ( isset( $this->params['userprefix'] ) ) {
* @return void
*/
private function run( $resultPageSet = null ) {
- $this->selectNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
+ $this->selectNamedDB( 'watchlist', DB_REPLICA, 'watchlist' );
$params = $this->extractRequestParams();
* @return string|null TS_MW timestamp or null
*/
private static function lastEditTime( User $user ) {
- $time = wfGetDB( DB_SLAVE )->selectField(
+ $time = wfGetDB( DB_REPLICA )->selectField(
'recentchanges',
'MAX(rc_timestamp)',
[ 'rc_user_text' => $user->getName() ],
}
protected static function validateLogId( $logid ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->selectField( 'logging', 'log_id', [ 'log_id' => $logid ],
__METHOD__ );
return (bool)$result;
: $warning['file'];
$warnings[$warning['warning']] = $localFile->getName();
}
+
+ if ( isset( $warnings['no-change'] ) ) {
+ /** @var File $file */
+ $file = $warnings['no-change'];
+ unset( $warnings['no-change'] );
+
+ $warnings['nochange'] = [
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() )
+ ];
+ }
+
+ if ( isset( $warnings['duplicate-version'] ) ) {
+ $dupes = [];
+ /** @var File $dupe */
+ foreach ( $warnings['duplicate-version'] as $dupe ) {
+ $dupes[] = [
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $dupe->getTimestamp() )
+ ];
+ }
+ unset( $warnings['duplicate-version'] );
+
+ ApiResult::setIndexedTagName( $dupes, 'ver' );
+ $warnings['duplicateversions'] = $dupes;
+ }
}
return $warnings;
"apihelp-protect-param-expiry": "Horodatages d’expiration. Si un seul horodatage est fourni, il sera utilisé pour toutes les protections. Utiliser <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd> ou <kbd>never</kbd> pour une protection sans expiration.",
"apihelp-protect-param-reason": "Motif de (dé)protection.",
"apihelp-protect-param-tags": "Modifier les balises à appliquer à l’entrée dans le journal de protection.",
- "apihelp-protect-param-cascade": "Activer la protection en cascade (c’est-à-dire protéger les modèles transclus et les images utilisées dans cette page). Ignoré si aucun des niveaux de protection fournis ne supporte la mise en cascade.",
+ "apihelp-protect-param-cascade": "Activer la protection en cascade (c’est-à-dire protéger les modèles transclus et les images utilisées dans cette page). Ignoré si aucun des niveaux de protection fournis ne prend en charge la mise en cascade.",
"apihelp-protect-param-watch": "Si activé, ajouter la page (dé)protégée à la liste de suivi de l'utilisateur actuel.",
"apihelp-protect-param-watchlist": "Ajouter ou supprimer sans condition la page de la liste de suivi de l'utilisateur actuel, utiliser les préférences ou ne pas modifier le suivi.",
"apihelp-protect-example-protect": "Protéger une page",
"apihelp-query+search-paramvalue-prop-sectiontitle": "Ajoute le titre de la section correspondante.",
"apihelp-query+search-paramvalue-prop-categorysnippet": "Ajoute un extrait analysé de la catégorie correspondante.",
"apihelp-query+search-paramvalue-prop-isfilematch": "Ajoute un booléen indiquant si la recherche correspond au contenu du fichier.",
- "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">Obsolète et ignoré.</span>",
+ "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">Désuet et ignoré.</span>",
"apihelp-query+search-paramvalue-prop-hasrelated": "<span class=\"apihelp-deprecated\">Obsolète et ignoré.</span>",
"apihelp-query+search-param-limit": "Combien de pages renvoyer au total.",
"apihelp-query+search-param-interwiki": "Inclure les résultats interwiki dans la recherche, s’ils sont disponibles.",
"apihelp-query+siteinfo-paramvalue-prop-fileextensions": "Renvoie la liste des extensions de fichier (types de fichier) autorisées au téléchargement.",
"apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Renvoie l’information sur les droits du wiki (sa licence), si elle est disponible.",
"apihelp-query+siteinfo-paramvalue-prop-restrictions": "Renvoie l’information sur les types de restriction disponibles (protection).",
- "apihelp-query+siteinfo-paramvalue-prop-languages": "Renvoie une liste des langues que supporte MédiaWiki (éventuellement localisé en utilisant <var>$1inlanguagecode</var>).",
+ "apihelp-query+siteinfo-paramvalue-prop-languages": "Renvoie une liste des langues que MédiaWiki prend en charge (éventuellement localisée en utilisant <var>$1inlanguagecode</var>).",
"apihelp-query+siteinfo-paramvalue-prop-skins": "Renvoie une liste de tous les habillages activés (éventuellement localisé en utilisant <var>$1inlanguagecode</var>, sinon dans la langue du contenu).",
"apihelp-query+siteinfo-paramvalue-prop-extensiontags": "Renvoie une liste des balises d’extension de l’analyseur.",
"apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Renvoie une liste des accroches de fonction de l’analyseur.",
"api-pageset-param-generator": "Obtenir la liste des pages sur lesquelles travailler en exécutant le module de recherche spécifié.\n\n<strong>NOTE :<strong> les noms de paramètre du générateur doivent être préfixés avec un « g », voir les exemples.",
"api-pageset-param-redirects-generator": "Résoudre automatiquement les redirections dans <var>$1titles</var>, <var>$1pageids</var> et <var>$1revids</var>, et dans les pages renvoyées par <var>$1generator</var>.",
"api-pageset-param-redirects-nogenerator": "Résoudre automatiquement les redirections dans <var>$1titles</var>, <var>$1pageids</var> et <var>$1revids</var>.",
- "api-pageset-param-converttitles": "Convertir les titres dans d’autres variantes si nécessaire. Fonctionne uniquement si la langue de contenu du wiki supporte la conversion en variantes. Les langues qui supportent la conversion en variante incluent $1.",
+ "api-pageset-param-converttitles": "Convertir les titres dans d’autres variantes si nécessaire. Fonctionne uniquement si la langue de contenu du wiki prend en charge la conversion en variantes. Les langues qui prennent en charge la conversion en variante incluent $1.",
"api-help-title": "Aide de l’API de MediaWiki",
"api-help-lead": "Ceci est une page d’aide de l’API de MediaWiki générée automatiquement.\n\nDocumentation et exemples : https://www.mediawiki.org/wiki/API",
"api-help-main-header": "Module principal",
"apihelp-options-example-change": "לשנות את ההעדפות <kbd>skin</kbd> ו־<kbd>hideminor</kbd>.",
"apihelp-options-example-complex": "לאתחל את כל ההעדפות ואז להגדיר את <kbd>skin</kbd> ואת <kbd>nickname</kbd>.",
"apihelp-paraminfo-description": "קבלת מידע על יחידות של API.",
- "apihelp-paraminfo-param-modules": "רשימה של שמות יחידות (ערכים של הפרמטרים <var>action</var> ו־<var>format</var>, או <kbd>main</kbd>). אפשר להגדיר תת־יחידות עם <kbd>+</kbd>.",
+ "apihelp-paraminfo-param-modules": "רשימה של שמות יחידות (ערכים של הפרמטרים <var>action</var> ו־<var>format</var>, או <kbd>main</kbd>). אפשר להגדיר תת־יחידות עם <kbd>+</kbd>, או כל התת־מודולים עם <kbd dir=\"ltr\">+*</kbd>, או כל התת־מודולים באופן רקורסיבי עם <kbd dir=\"ltr\">+**</kbd>.",
"apihelp-paraminfo-param-helpformat": "תסדיר מחרוזות העזרה.",
"apihelp-paraminfo-param-querymodules": "רשימת שמות יחידות query (ערך של הפרמטר <var>prop</var>, <var>meta</var> או <var>list</var>). יש להשתמש ב־<kbd>$1modules=query+foo</kbd> במקום <kbd>$1querymodules=foo</kbd>.",
"apihelp-paraminfo-param-mainmodule": "קבלת מידע עם היחידה הראשית (העליונה). יש להשתמש ב־<kbd>$1modules=main</kbd> במקום זה.",
"apihelp-paraminfo-param-pagesetmodule": "קבלת מידע גם על יחידת pageset (שמספק את titles= וידידיו).",
"apihelp-paraminfo-param-formatmodules": "רשימת שמות תסדירים (ערכים של הפרמטר <var>format</var>). יש להשתמש ב־<var>$1modules</var> במקום זה.",
"apihelp-paraminfo-example-1": "הצגת מידע עבור <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, ו־<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+ "apihelp-paraminfo-example-2": "הצגת מידע עבור כל התת־מודולים של <kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
"apihelp-parse-description": "מפענח את התוכן ומחזיר פלט מפענח.\n\nר' את יחידת ה־prop השיונות של <kbd>[[Special:ApiHelp/query|action=query]]</kbd> כדי לקבל מידע על הגרסה הנוכחית של הדף.\n\nיש מספר דרכים לציין טקסט לפענוח:\n# ציון דף או גרסה באמצעות <var>$1page</var>, <var>$1pageid</var>, או <var>$1oldid</var>.\n# ציון התוכן במפורש, באמצעות <var>$1text</var>, <var>$1title</var>, ו־<var>$1contentmodel</var>.\n# ציון רק של התקציר לפענוח. ל־<var>$1prop</var> צריך לתת ערך ריק.",
"apihelp-parse-param-title": "שם הדף שהטקסט שייך אליו. אם זה מושמט, יש לציין את <var>$1contentmodel</var>, ו־[[API]] ישמש ככותרת.",
"apihelp-parse-param-text": "הטקסט לפענוח. יש להשתמש ב־<var>$1title</var> או ב־<var>$1contentmodel</var>.",
"api-help-param-deprecated": "Застарілий.",
"api-help-param-required": "Цей параметр є обов'язковим.",
"api-help-datatypes-header": "Типи даних",
- "api-help-datatypes": "Ð\94еÑ\8fкÑ\96 Ñ\82ипи паÑ\80амеÑ\82Ñ\80Ñ\96в Ñ\83 запиÑ\82аÑ\85 API поÑ\82Ñ\80ебÑ\83Ñ\8eÑ\82Ñ\8c Ñ\88иÑ\80Ñ\88ого поÑ\8fÑ\81неннÑ\8f:\n;boolean\n:Ð\9bогÑ\96Ñ\87нÑ\96 паÑ\80амеÑ\82Ñ\80и пÑ\80аÑ\86Ñ\8eÑ\8eÑ\82Ñ\8c Ñ\8fк галоÑ\87ки HTML: Ñ\8fкÑ\89о паÑ\80амеÑ\82Ñ\80 вказано, не залежно вÑ\96д знаÑ\87еннÑ\8f, вÑ\96н вважаÑ\94Ñ\82Ñ\8cÑ\81Ñ\8f Ñ\96Ñ\81Ñ\82инним. Щоб знаÑ\87еннÑ\8f бÑ\83ло Ñ\85ибним, пÑ\80опÑ\83Ñ\81Ñ\82Ñ\96Ñ\82Ñ\8c паÑ\80амеÑ\82Ñ\80 зовÑ\81Ñ\96м.\n;timestamp\n:ЧаÑ\81овÑ\96 мÑ\96Ñ\82ки можÑ\83Ñ\82Ñ\8c бÑ\83Ñ\82и вказанÑ\96 Ñ\83 кÑ\96лÑ\8cкоÑ\85 Ñ\84оÑ\80маÑ\82аÑ\85. РекомендÑ\83Ñ\94Ñ\82Ñ\8cÑ\81Ñ\8f Ñ\87аÑ\81 Ñ\96 даÑ\82а в ISO 8601. УÑ\81Ñ\96 знаÑ\87еннÑ\8f Ñ\87аÑ\81Ñ\83 в UTC, бÑ\83дÑ\8c-Ñ\8fкÑ\96 Ñ\87аÑ\81овÑ\96 поÑ\8fÑ\81и Ñ\96гноÑ\80Ñ\83Ñ\8eÑ\82Ñ\8cÑ\81Ñ\8f.\n:* Ð\94аÑ\82а Ñ\96 Ñ\87аÑ\81 ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (пÑ\83нкÑ\82Ñ\83аÑ\86Ñ\96Ñ\8f Ñ\96 <kbd>Z</kbd> необов'Ñ\8fзоквÑ\96)\n:* Ð\94аÑ\82а Ñ\96 Ñ\87аÑ\81 ISO 8601 з (Ñ\96гноÑ\80ованими) Ñ\87аÑ\81Ñ\82ками Ñ\81екÑ\83нди, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (деÑ\84Ñ\96Ñ\81и, двокÑ\80апки Ñ\82а <kbd>Z</kbd> необов'Ñ\8fзковÑ\96)\n:* ФоÑ\80маÑ\82 MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Ð\97агалÑ\8cний Ñ\87иÑ\81ловий Ñ\84оÑ\80маÑ\82, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (необов'Ñ\8fзковий Ñ\87аÑ\81овий поÑ\8fÑ\81 <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd> або <kbd>-<var>##</var></kbd> Ñ\96гноÑ\80Ñ\83Ñ\94Ñ\82Ñ\8cÑ\81Ñ\8f)\n:* ФоÑ\80маÑ\82 EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 RFC 2822 (Ñ\87аÑ\81овий поÑ\8fÑ\81 може бÑ\83Ñ\82и опÑ\83Ñ\89ений), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 RFC 850 (Ñ\87аÑ\81овий поÑ\8fÑ\81 може бÑ\83Ñ\82и опÑ\83Ñ\89ений), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* СекÑ\83нди вÑ\96д 1970-01-01T00:00:00Z Ñ\83 виглÑ\8fдÑ\96 Ñ\86Ñ\96лого Ñ\87иÑ\81ла вÑ\96д 1 до 13 Ñ\86иÑ\84Ñ\80 (без <kbd>0</kbd>)\n:* Ð Ñ\8fдок <kbd>now</kbd>",
+ "api-help-datatypes": "Ð\92Ñ\85Ñ\96днÑ\96 данÑ\96 Ñ\83 MediaWiki маÑ\8eÑ\82Ñ\8c бÑ\83Ñ\82и в NFC-ноÑ\80малÑ\96зованомÑ\83 UTF-8. MediaWiki може Ñ\81пÑ\80обÑ\83ваÑ\82и конвеÑ\80Ñ\82Ñ\83ваÑ\82и вÑ\85Ñ\96днÑ\96 данÑ\96 Ñ\96нÑ\88ого виглÑ\8fдÑ\83, але вÑ\96д Ñ\86Ñ\8cого можÑ\83Ñ\82Ñ\8c поÑ\81Ñ\82Ñ\80аждаÑ\82и деÑ\8fкÑ\96 опеÑ\80аÑ\86Ñ\96Ñ\97 (Ñ\8fк [[Special:ApiHelp/edit|Ñ\80едагÑ\83ваннÑ\8f]] з пеÑ\80евÑ\96Ñ\80коÑ\8e MD5).\n\nÐ\94еÑ\8fкÑ\96 Ñ\82ипи паÑ\80амеÑ\82Ñ\80Ñ\96в Ñ\83 запиÑ\82аÑ\85 API поÑ\82Ñ\80ебÑ\83Ñ\8eÑ\82Ñ\8c Ñ\88иÑ\80Ñ\88ого поÑ\8fÑ\81неннÑ\8f:\n;boolean\n:Ð\9bогÑ\96Ñ\87нÑ\96 паÑ\80амеÑ\82Ñ\80и пÑ\80аÑ\86Ñ\8eÑ\8eÑ\82Ñ\8c Ñ\8fк галоÑ\87ки HTML: Ñ\8fкÑ\89о паÑ\80амеÑ\82Ñ\80 вказано, не залежно вÑ\96д знаÑ\87еннÑ\8f, вÑ\96н вважаÑ\94Ñ\82Ñ\8cÑ\81Ñ\8f Ñ\96Ñ\81Ñ\82инним. Щоб знаÑ\87еннÑ\8f бÑ\83ло Ñ\85ибним, пÑ\80опÑ\83Ñ\81Ñ\82Ñ\96Ñ\82Ñ\8c паÑ\80амеÑ\82Ñ\80 зовÑ\81Ñ\96м.\n;timestamp\n:ЧаÑ\81овÑ\96 мÑ\96Ñ\82ки можÑ\83Ñ\82Ñ\8c бÑ\83Ñ\82и вказанÑ\96 Ñ\83 кÑ\96лÑ\8cкоÑ\85 Ñ\84оÑ\80маÑ\82аÑ\85. РекомендÑ\83Ñ\94Ñ\82Ñ\8cÑ\81Ñ\8f Ñ\87аÑ\81 Ñ\96 даÑ\82а в ISO 8601. УÑ\81Ñ\96 знаÑ\87еннÑ\8f Ñ\87аÑ\81Ñ\83 в UTC, бÑ\83дÑ\8c-Ñ\8fкÑ\96 Ñ\87аÑ\81овÑ\96 поÑ\8fÑ\81и Ñ\96гноÑ\80Ñ\83Ñ\8eÑ\82Ñ\8cÑ\81Ñ\8f.\n:* Ð\94аÑ\82а Ñ\96 Ñ\87аÑ\81 ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (пÑ\83нкÑ\82Ñ\83аÑ\86Ñ\96Ñ\8f Ñ\96 <kbd>Z</kbd> необов'Ñ\8fзоквÑ\96)\n:* Ð\94аÑ\82а Ñ\96 Ñ\87аÑ\81 ISO 8601 з (Ñ\96гноÑ\80ованими) Ñ\87аÑ\81Ñ\82ками Ñ\81екÑ\83нди, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (деÑ\84Ñ\96Ñ\81и, двокÑ\80апки Ñ\82а <kbd>Z</kbd> необов'Ñ\8fзковÑ\96)\n:* ФоÑ\80маÑ\82 MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Ð\97агалÑ\8cний Ñ\87иÑ\81ловий Ñ\84оÑ\80маÑ\82, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (необов'Ñ\8fзковий Ñ\87аÑ\81овий поÑ\8fÑ\81 <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd> або <kbd>-<var>##</var></kbd> Ñ\96гноÑ\80Ñ\83Ñ\94Ñ\82Ñ\8cÑ\81Ñ\8f)\n:* ФоÑ\80маÑ\82 EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 RFC 2822 (Ñ\87аÑ\81овий поÑ\8fÑ\81 може бÑ\83Ñ\82и опÑ\83Ñ\89ений), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 RFC 850 (Ñ\87аÑ\81овий поÑ\8fÑ\81 може бÑ\83Ñ\82и опÑ\83Ñ\89ений), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* ФоÑ\80маÑ\82 C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* СекÑ\83нди вÑ\96д 1970-01-01T00:00:00Z Ñ\83 виглÑ\8fдÑ\96 Ñ\86Ñ\96лого Ñ\87иÑ\81ла вÑ\96д 1 до 13 Ñ\86иÑ\84Ñ\80 (без <kbd>0</kbd>)\n:* Ð Ñ\8fдок <kbd>now</kbd>\n;алÑ\8cÑ\82еÑ\80наÑ\82ивний Ñ\80оздÑ\96лÑ\8cник багаÑ\82Ñ\8cоÑ\85 знаÑ\87енÑ\8c\n:Ð\9fаÑ\80амеÑ\82Ñ\80и, Ñ\89о пÑ\80иймаÑ\8eÑ\82Ñ\8c багаÑ\82о знаÑ\87енÑ\8c, зазвиÑ\87ай подаÑ\8eÑ\82Ñ\8cÑ\81Ñ\8f зÑ\96 знаÑ\87еннÑ\8fми, Ñ\80оздÑ\96леними веÑ\80Ñ\82икалÑ\8cноÑ\8e Ñ\80иÑ\81коÑ\8e, напÑ\80иклад, <kbd>param=value1|value2</kbd> або <kbd>param=value1%7Cvalue2</kbd>. ЯкÑ\89о знаÑ\87еннÑ\8f повинне мÑ\96Ñ\81Ñ\82иÑ\82и веÑ\80Ñ\82икалÑ\8cнÑ\83 Ñ\80иÑ\81кÑ\83, викоÑ\80иÑ\81Ñ\82овÑ\83йÑ\82е Ñ\8fк Ñ\80оздÑ\96лÑ\8cник U+001F (Ñ\80оздÑ\96лÑ\8cник одиниÑ\86Ñ\8c) ''Ñ\82а'' поÑ\81Ñ\82авÑ\82е U+001F пеÑ\80ед знаÑ\87еннÑ\8fм, напÑ\80иклад, <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
"api-help-param-type-limit": "Тип: ціле число або <kbd>max</kbd>",
"api-help-param-type-integer": "Тип: {{PLURAL:$1|1=ціле число|2=список цілих чисел}}",
"api-help-param-type-boolean": "Тип: логічний ([[Special:ApiHelp/main#main/datatypes|деталі]])",
"api-help-param-type-timestamp": "Тип: {{PLURAL:$1|1=часова мітка|2=список часових міток}} ([[Special:ApiHelp/main#main/datatypes|дозволені формати]])",
"api-help-param-type-user": "Тип: {{PLURAL:$1|1=ім'я користувача|2=список імен користувачів}}",
- "api-help-param-list": "{{PLURAL:$1|1=Одне з наступних значень|2=Значення (розділені через <kbd>{{!}}</kbd>)}}: $2",
+ "api-help-param-list": "{{PLURAL:$1|1=Одне з наступних значень|2=Значення (розділені через <kbd>{{!}}</kbd> або [[Special:ApiHelp/main#main/datatypes|альтернативу]])}}: $2",
"api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Повинно бути пустим|Може бути пустим або $2}}",
"api-help-param-limit": "Дозволено не більше $1.",
"api-help-param-limit2": "Дозволено не більше $1 ($2 для ботів).",
"api-help-param-integer-max": "{{PLURAL:$1|1=Значення має бути|2=Значення мають бути}} не більше $3.",
"api-help-param-integer-minmax": "{{PLURAL:$1|1=Значення має бути|2=Значення мають бути}} між $2 і $3.",
"api-help-param-upload": "Повинно бути надіслано у формі надсилання файлу використовуючи multipart/form-data.",
- "api-help-param-multi-separate": "Розділіть значення з допомогою <kbd>|</kbd>.",
+ "api-help-param-multi-separate": "Розділіть значення з допомогою <kbd>|</kbd> або [[Special:ApiHelp/main#main/datatypes|альтернативу]].",
"api-help-param-multi-max": "Максимальна кількість значень — {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} для ботів).",
"api-help-param-default": "За замовчуванням: $1",
"api-help-param-default-empty": "За замовчуванням: <span class=\"apihelp-empty\">(пусто)</span>",
"apihelp-options-example-change": "更改<kbd>skin</kbd>和<kbd>hideminor</kbd>设置。",
"apihelp-options-example-complex": "重置所有设置,然后设置<kbd>skin</kbd>和<kbd>nickname</kbd>。",
"apihelp-paraminfo-description": "获得关于API模块的信息。",
- "apihelp-paraminfo-param-modules": "模块名称(<var>action</var>和<var>format</var>参数值,或<kbd>main</kbd>)的列表。可通过<kbd>+</kbd>指定子模块。",
+ "apihelp-paraminfo-param-modules": "模块名称(<var>action</var>和<var>format</var>参数值,或<kbd>main</kbd>)的列表。可通过<kbd>+</kbd>指定子模块,或通过<kbd>+*</kbd>指定所有子模块,或通过<kbd>+**</kbd>指定所有递归子模块。",
"apihelp-paraminfo-param-helpformat": "帮助字符串的格式。",
"apihelp-paraminfo-param-querymodules": "查询模块名称(<var>prop</var>、<var>meta</var>或<var>list</var>参数值)的列表。使用<kbd>$1modules=query+foo</kbd>而不是<kbd>$1querymodules=foo</kbd>。",
"apihelp-paraminfo-param-mainmodule": "获取有关主要(最高级)模块的信息。也可使用<kbd>$1modules=main</kbd>。",
"apihelp-paraminfo-param-pagesetmodule": "获取有关页面设置模块(提供titles=和朋友)的信息。",
"apihelp-paraminfo-param-formatmodules": "格式模块名称(<var>format</var>参数的值)的列表。也可使用<var>$1modules</var>。",
"apihelp-paraminfo-example-1": "显示<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>、<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>、<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>和<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>的信息。",
+ "apihelp-paraminfo-example-2": "显示<kbd>[[Special:ApiHelp/query|action=query]]</kbd>的所有子模块的信息。",
"apihelp-parse-description": "解析内容并返回解析器输出。\n\n参见<kbd>[[Special:ApiHelp/query|action=query]]</kbd>的各种prop-module以从页面的当前版本获得信息。\n\n这里有几种方法可以指定解析的文本:\n# 指定一个页面或修订,使用<var>$1page</var>、<var>$1pageid</var>或<var>$1oldid</var>。\n# 明确指定内容,使用<var>$1text</var>、<var>$1title</var>和<var>$1contentmodel</var>。\n# 只指定一段摘要解析。<var>$1prop</var>应提供一个空值。",
"apihelp-parse-param-title": "文本属于的页面标题。如果省略,<var>$1contentmodel</var>就必须被指定,且[[API]]将作为标题使用。",
"apihelp-parse-param-text": "要解析的文本。使用<var>$1title</var>或<var>$1contentmodel</var>以控制内容模型。",
$username = $user->getName();
- // Try the local user from the slave DB
+ // Try the local user from the replica DB
$localId = User::idFromName( $username );
$flags = User::READ_NORMAL;
return AuthenticationResponse::newAbstain();
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'user',
[
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'user',
[ 'user_newpassword', 'user_newpass_time' ],
}
/**
- * Get the slave connection to the database
+ * Get the replica DB connection to the database
* When non existing, will initialize the connection.
* @return DatabaseBase
*/
protected function getDB() {
if ( !isset( $this->db ) ) {
- $this->db = wfGetDB( DB_SLAVE );
+ $this->db = wfGetDB( DB_REPLICA );
}
return $this->db;
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = [ 'user', 'user_properties' ];
$fields = [ 'user_name', 'up_value' ];
$conds = [ 'user_name' => $usersToCheck ];
}
// This is similar to LinkHolderArray::replaceInternal
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = 'page';
$fields = array_merge(
LinkCache::getSelectFields(),
}
// Some fields heavily used for linking...
- $db = $this->mForUpdate ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
+ $db = $this->mForUpdate ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
$row = $db->selectRow( 'page', self::getSelectFields(),
[ 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ],
$cache->set( $cacheKey, $blob,
// Add part of a day to TTL to avoid all modules expiring at once
$cache::TTL_WEEK + mt_rand( 0, $cache::TTL_DAY ),
- Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) )
+ Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) )
);
return $blob;
}
public function updateMessage( $key ) {
$moduleNames = $this->getResourceLoader()->getModulesByMessage( $key );
foreach ( $moduleNames as $moduleName ) {
- // Uses a holdoff to account for database slave lag (for MessageCache)
+ // Uses a holdoff to account for database replica DB lag (for MessageCache)
$this->wanCache->touchCheckKey( $this->wanCache->makeKey( __CLASS__, $moduleName ) );
}
}
$where[] = 'global cache is expired';
$staleCache = $cache;
} elseif ( $hashVolatile ) {
- # DB results are slave lag prone until the holdoff TTL passes.
+ # DB results are replica DB lag prone until the holdoff TTL passes.
# By then, updates should be reflected in loadFromDBWithLock().
# One thread renerates the cache while others use old values.
$where[] = 'global cache is expired/volatile';
function loadFromDB( $code, $mode = null ) {
global $wgMaxMsgCacheEntrySize, $wgLanguageCode, $wgAdaptiveMessageCache;
- $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_SLAVE );
+ $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_REPLICA );
$cache = [];
}
// Mark this cache as definitely "latest" (non-volatile) so
- // load() calls do try to refresh the cache with slave data
+ // load() calls do try to refresh the cache with replica DB data
$this->mCache[$code]['LATEST'] = time();
// Update caches if the lock was acquired
// Lookup basic info for users not yet loaded...
if ( count( $usersToQuery ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$table = [ 'user' ];
$conds = [ 'user_id' => $usersToQuery ];
$fields = [ 'user_name', 'user_real_name', 'user_registration', 'user_id' ];
if ( $this->writesDone && $this->dbw ) {
$db = $this->dbw; // see the changes in finishWrite()
} else {
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
}
$value = $db->selectField(
/**
* T109700 - Default bot flag to true when there is no corresponding RC entry
* This means all changes caused by parser functions & Lua on reparse are marked as bot
- * Also in the case no RC entry could be found due to slave lag
+ * Also in the case no RC entry could be found due to replica DB lag
*/
$bot = 1;
$lastRevId = 0;
public static function newFromConds(
$conds,
$fname = __METHOD__,
- $dbType = DB_SLAVE
+ $dbType = DB_REPLICA
) {
$db = wfGetDB( $dbType );
$row = $db->selectRow( 'recentchanges', self::selectFields(), $conds, $fname );
// Might as well look for rcids and so on.
if ( !$rc_id ) {
- // Info might be out of date, somewhat fractionally, on slave.
+ // Info might be out of date, somewhat fractionally, on replica DB.
// LogEntry/LogPage and WikiPage match rev/log/rc timestamps,
// so use that relation to avoid full table scans.
if ( $log_id ) {
);
}
} elseif ( !$log_id && !$rev_id ) {
- // Info might be out of date, somewhat fractionally, on slave.
+ // Info might be out of date, somewhat fractionally, on replica DB.
$log_id = $dbw->selectField(
'recentchanges',
'rc_logid',
$tagsToAdd = array_diff( $tagsToAdd, $tagsToRemove );
// Update the summary row.
- // $prevTags can be out of date on slaves, especially when addTags is called consecutively,
+ // $prevTags can be out of date on replica DBs, especially when addTags is called consecutively,
// causing loss of tags added recently in tag_summary table.
$prevTags = $dbw->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
$prevTags = $prevTags ? $prevTags : '';
throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
}
- $fields['ts_tags'] = wfGetDB( DB_SLAVE )->buildGroupConcatField(
+ $fields['ts_tags'] = wfGetDB( DB_REPLICA )->buildGroupConcatField(
',', 'change_tag', 'ct_tag', $join_cond
);
wfMemcKey( 'active-tags' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
// Ask extensions which tags they consider active
$extensionActive = [];
wfMemcKey( 'valid-tags-db' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
wfMemcKey( 'valid-tags-hook' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
$tags = [];
Hooks::run( 'ListDefinedTags', [ &$tags ] );
wfMemcKey( 'change-tag-statistics' ),
WANObjectCache::TTL_MINUTE * 5,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
- $dbr = wfGetDB( DB_SLAVE, 'vslow' );
+ $dbr = wfGetDB( DB_REPLICA, 'vslow' );
$setOpts += Database::getCacheSetOptions( $dbr );
* have it / want it.
*/
public function getAutoDeleteReason( Title $title, &$hasHistory ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Get the last revision
$rev = Revision::newFromTitle( $title );
* Get an appropriate DB index and options for a query
*
* @param integer $bitfield
- * @return array (DB_MASTER/DB_SLAVE, SELECT options array)
+ * @return array (DB_MASTER/DB_REPLICA, SELECT options array)
*/
public static function getDBOptions( $bitfield ) {
$index = self::hasFlags( $bitfield, IDBAccessObject::READ_LATEST )
? DB_MASTER
- : DB_SLAVE;
+ : DB_REPLICA;
$options = [];
if ( self::hasFlags( $bitfield, IDBAccessObject::READ_EXCLUSIVE ) ) {
* though certain objects may assume READ_LATEST for common use case or legacy reasons.
*
* There are four types of reads:
- * - READ_NORMAL : Potentially cached read of data (e.g. from a slave or stale replica)
+ * - READ_NORMAL : Potentially cached read of data (e.g. from a replica DB or stale replica)
* - READ_LATEST : Up-to-date read as of transaction start (e.g. from master or a quorum read)
* - READ_LOCKING : Up-to-date read as of now, that locks (shared) the records
* - READ_EXCLUSIVE : Up-to-date read as of now, that locks (exclusive) the records
* All record locks persist for the duration of the transaction.
*
* A special constant READ_LATEST_IMMUTABLE can be used for fetching append-only data. Such
- * data is either (a) on a slave and up-to-date or (b) not yet there, but on the master/quorum.
- * Because the data is append-only, it can never be stale on a slave if present.
+ * data is either (a) on a replica DB and up-to-date or (b) not yet there, but on the master/quorum.
+ * Because the data is append-only, it can never be stale on a replica DB if present.
*
* Callers should use READ_NORMAL (or pass in no flags) unless the read determines a write.
* In theory, such cases may require READ_LOCKING, though to avoid contention, READ_LATEST is
*/
interface IDBAccessObject {
/** Constants for object loading bitfield flags (higher => higher QoS) */
- /** @var integer Read from a slave/non-quorum */
+ /** @var integer Read from a replica DB/non-quorum */
const READ_NORMAL = 0;
/** @var integer Read from the master/quorum */
const READ_LATEST = 1;
/** @var integer Read from the master/quorum and lock out other writers and locking readers */
const READ_EXCLUSIVE = 7; // READ_LOCKING (3) and "FOR UPDATE" (4)
- /** @var integer Read from a slave/non-quorum immutable data, using the master/quorum on miss */
+ /** @var integer Read from a replica DB or without a quorum, using the master/quorum on miss */
const READ_LATEST_IMMUTABLE = 8;
// Convenience constant for tracking how data was loaded (higher => higher QoS)
* Initialise a LoadBalancer to give it appropriate chronology protection.
*
* If the stash has a previous master position recorded, this will try to
- * make sure that the next query to a slave of that master will see changes up
+ * make sure that the next query to a replica DB of that master will see changes up
* to that position by delaying execution. The delay may timeout and allow stale
- * data if no non-lagged slaves are available.
+ * data if no non-lagged replica DBs are available.
*
* @param LoadBalancer $lb
* @return void
*/
private $mTrxTimestamp = null;
/** @var float Lag estimate at the time of BEGIN */
- private $mTrxSlaveLag = null;
+ private $mTrxReplicaLag = null;
/**
* Remembers the function name given for starting the most recent transaction via begin().
* Used to provide additional context for error reporting.
* @param float $runtime Total runtime, including RTT
*/
private function updateTrxWriteQueryTime( $sql, $runtime ) {
- $indicativeOfSlaveRuntime = true;
+ // Whether this is indicative of replica DB runtime (except for RBR or ws_repl)
+ $indicativeOfReplicaRuntime = true;
if ( $runtime > self::SLOW_WRITE_SEC ) {
$verb = $this->getQueryVerb( $sql );
// insert(), upsert(), replace() are fast unless bulky in size or blocked on locks
if ( $verb === 'INSERT' ) {
- $indicativeOfSlaveRuntime = $this->affectedRows() > self::SMALL_WRITE_ROWS;
+ $indicativeOfReplicaRuntime = $this->affectedRows() > self::SMALL_WRITE_ROWS;
} elseif ( $verb === 'REPLACE' ) {
- $indicativeOfSlaveRuntime = $this->affectedRows() > self::SMALL_WRITE_ROWS / 2;
+ $indicativeOfReplicaRuntime = $this->affectedRows() > self::SMALL_WRITE_ROWS / 2;
}
}
$this->mTrxWriteDuration += $runtime;
$this->mTrxWriteQueryCount += 1;
- if ( $indicativeOfSlaveRuntime ) {
+ if ( $indicativeOfReplicaRuntime ) {
$this->mTrxWriteAdjDuration += $runtime;
$this->mTrxWriteAdjQueryCount += 1;
}
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
+ /**
+ * @param string $field Field or column to cast
+ * @return string
+ * @since 1.28
+ */
+ public function buildStringCast( $field ) {
+ return $field;
+ }
+
public function selectDB( $db ) {
# Stub. Shouldn't cause serious problems if it's not overridden, but
# if your database engine supports a concept similar to MySQL's
$this->mTrxWriteAdjQueryCount = 0;
$this->mTrxWriteCallers = [];
// First SELECT after BEGIN will establish the snapshot in REPEATABLE-READ.
- // Get an estimate of the slave lag before then, treating estimate staleness
+ // Get an estimate of the replica DB lag before then, treating estimate staleness
// as lag itself just to be safe
$status = $this->getApproximateLagStatus();
- $this->mTrxSlaveLag = $status['lag'] + ( microtime( true ) - $status['since'] );
+ $this->mTrxReplicaLag = $status['lag'] + ( microtime( true ) - $status['since'] );
}
/**
}
/**
- * Get the slave lag when the current transaction started
+ * Get the replica DB lag when the current transaction started
*
* This is useful when transactions might use snapshot isolation
* (e.g. REPEATABLE-READ in innodb), so the "real" lag of that data
*/
public function getTransactionLagStatus() {
return $this->mTrxLevel
- ? [ 'lag' => $this->mTrxSlaveLag, 'since' => $this->trxTimestamp() ]
+ ? [ 'lag' => $this->mTrxReplicaLag, 'since' => $this->trxTimestamp() ]
: null;
}
/**
- * Get a slave lag estimate for this server
+ * Get a replica DB lag estimate for this server
*
* @return array ('lag': seconds or false on error, 'since': UNIX timestamp of estimate)
* @since 1.27
*/
public function getApproximateLagStatus() {
return [
- 'lag' => $this->getLBInfo( 'slave' ) ? $this->getLag() : 0,
+ 'lag' => $this->getLBInfo( 'replica' ) ? $this->getLag() : 0,
'since' => microtime( true )
];
}
*/
abstract class DatabaseMysqlBase extends Database {
/** @var MysqlMasterPos */
- protected $lastKnownSlavePos;
- /** @var string Method to detect slave lag */
+ protected $lastKnownReplicaPos;
+ /** @var string Method to detect replica DB lag */
protected $lagDetectionMethod;
- /** @var array Method to detect slave lag */
+ /** @var array Method to detect replica DB lag */
protected $lagDetectionOptions = [];
/** @var bool bool Whether to use GTID methods */
protected $useGTIDs = false;
$key = $cache->makeGlobalKey(
'mysql',
'master-info',
- // Using one key for all cluster slaves is preferable
+ // Using one key for all cluster replica DBs is preferable
$this->getLBInfo( 'clusterMasterHost' ) ?: $this->getServer()
);
if ( $this->getLBInfo( 'is static' ) === true ) {
return 0; // this is a copy of a read-only dataset with no master DB
- } elseif ( $this->lastKnownSlavePos && $this->lastKnownSlavePos->hasReached( $pos ) ) {
+ } elseif ( $this->lastKnownReplicaPos && $this->lastKnownReplicaPos->hasReached( $pos ) ) {
return 0; // already reached this point for sure
}
if ( $status === null ) {
// T126436: jobs programmed to wait on master positions might be referencing binlogs
// with an old master hostname. Such calls make MASTER_POS_WAIT() return null. Try
- // to detect this and treat the slave as having reached the position; a proper master
+ // to detect this and treat the replica DB as having reached the position; a proper master
// switchover already requires that the new master be caught up before the switch.
- $slavePos = $this->getSlavePos();
- if ( $slavePos && !$slavePos->channelsMatch( $pos ) ) {
- $this->lastKnownSlavePos = $slavePos;
+ $replicationPos = $this->getSlavePos();
+ if ( $replicationPos && !$replicationPos->channelsMatch( $pos ) ) {
+ $this->lastKnownReplicaPos = $replicationPos;
$status = 0;
}
} elseif ( $status >= 0 ) {
// Remember that this position was reached to save queries next time
- $this->lastKnownSlavePos = $pos;
+ $this->lastKnownReplicaPos = $pos;
}
return $status;
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
+ /**
+ * @param string $field Field or column to cast
+ * @return string
+ * @since 1.28
+ */
+ public function buildStringCast( $field ) {
+ return 'CAST ( ' . $field . ' AS VARCHAR2 )';
+ }
+
public function getSearchEngine() {
return 'SearchOracle';
}
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
+ /**
+ * @param string $field Field or column to cast
+ * @return string
+ * @since 1.28
+ */
+ public function buildStringCast( $field ) {
+ return $field . '::text';
+ }
+
public function getSearchEngine() {
return 'SearchPostgres';
}
return parent::buildLike( $params ) . "ESCAPE '\' ";
}
+ /**
+ * @param string $field Field or column to cast
+ * @return string
+ * @since 1.28
+ */
+ public function buildStringCast( $field ) {
+ return 'CAST ( ' . $field . ' AS TEXT )';
+ }
+
/**
* @return string
*/
}
/**
- * An object representing a master or slave position in a replicated setup.
+ * An object representing a master or replica DB position in a replicated setup.
*
* The implementation details of this opaque type are up to the database subclass.
*/
public function wasReadOnlyError();
/**
- * Wait for the slave to catch up to a given master position
+ * Wait for the replica DB to catch up to a given master position
*
* @param DBMasterPos $pos
* @param int $timeout The maximum number of seconds to wait for synchronisation
- * @return int|null Zero if the slave was past that position already,
+ * @return int|null Zero if the replica DB was past that position already,
* greater than zero if we waited for some period of time, less than
* zero if it timed out, and null on error
*/
public function masterPosWait( DBMasterPos $pos, $timeout );
/**
- * Get the replication position of this slave
+ * Get the replication position of this replica DB
*
- * @return DBMasterPos|bool False if this is not a slave.
+ * @return DBMasterPos|bool False if this is not a replica DB.
*/
public function getSlavePos();
public function ping( &$rtt = null );
/**
- * Get slave lag. Currently supported only by MySQL.
+ * Get replica DB lag. Currently supported only by MySQL.
*
* Note that this function will generate a fatal error on many
* installations. Most callers should use LoadBalancer::safeGetLag()
public function getLag();
/**
- * Get the slave lag when the current transaction started
+ * Get the replica DB lag when the current transaction started
* or a general lag estimate if not transaction is active
*
* This is useful when transactions might use snapshot isolation
/**
* Commit on all connections. Done for two reasons:
* 1. To commit changes to the masters.
- * 2. To release the snapshot on all connections, master and slave.
+ * 2. To release the snapshot on all connections, master and replica DB.
* @param string $fname Caller name
* @param array $options Options map:
* - maxWriteDuration: abort if more than this much time was spent in write queries
}
/**
- * Detemine if any lagged slave connection was used
- * @since 1.27
+ * Detemine if any lagged replica DB connection was used
* @return bool
+ * @since 1.28
*/
- public function laggedSlaveUsed() {
+ public function laggedReplicaUsed() {
$ret = false;
$this->forEachLB( function ( LoadBalancer $lb ) use ( &$ret ) {
- $ret = $ret || $lb->laggedSlaveUsed();
+ $ret = $ret || $lb->laggedReplicaUsed();
} );
return $ret;
}
+ /**
+ * @return bool
+ * @since 1.27
+ * @deprecated Since 1.28; use laggedReplicaUsed()
+ */
+ public function laggedSlaveUsed() {
+ return $this->laggedReplicaUsed();
+ }
+
/**
* Determine if any master connection has pending/written changes from this request
* @return bool
}
/**
- * Waits for the slave DBs to catch up to the current master position
+ * Waits for the replica DBs to catch up to the current master position
*
* Use this when updating very large numbers of rows, as in maintenance scripts,
- * to avoid causing too much lag. Of course, this is a no-op if there are no slaves.
+ * to avoid causing too much lag. Of course, this is a no-op if there are no replica DBs.
*
* By default this waits on all DB clusters actually used in this request.
* This makes sense when lag being waiting on is caused by the code that does this check.
$masterPositions = array_fill( 0, count( $lbs ), false );
foreach ( $lbs as $i => $lb ) {
if ( $lb->getServerCount() <= 1 ) {
- // Bug 27975 - Don't try to wait for slaves if there are none
+ // Bug 27975 - Don't try to wait for replica DBs if there are none
// Prevents permission error when getting master position
continue;
} elseif ( $opts['ifWritesSince']
if ( $failed ) {
throw new DBReplicationWaitError(
- "Could not wait for slaves to catch up to " .
+ "Could not wait for replica DBs to catch up to " .
implode( ', ', $failed )
);
}
// Write them to the stash
$unsavedPositions = $cp->shutdown();
// If the positions failed to write to the stash, at least wait on local datacenter
- // slaves to catch up before responding. Even if there are several DCs, this increases
+ // replica DBs to catch up before responding. Even if there are several DCs, this increases
// the chance that the user will see their own changes immediately afterwards. As long
// as the sticky DC cookie applies (same domain), this is not even an issue.
$this->forEachLB( function ( LoadBalancer $lb ) use ( $unsavedPositions ) {
}
$master = false;
} else {
- $serverInfo['slave'] = true;
+ $serverInfo['replica'] = true;
}
if ( isset( $this->templateOverridesByServer[$serverName] ) ) {
$serverInfo = $this->templateOverridesByServer[$serverName] + $serverInfo;
if ( $i == 0 ) {
$server['master'] = true;
} else {
- $server['slave'] = true;
+ $server['replica'] = true;
}
$server += [ 'flags' => DBO_DEFAULT ];
}
private $mLoads;
/** @var array[] Map of (group => server index => weight) */
private $mGroupLoads;
- /** @var bool Whether to disregard slave lag as a factor in slave selection */
+ /** @var bool Whether to disregard replica DB lag as a factor in replica DB selection */
private $mAllowLagged;
- /** @var integer Seconds to spend waiting on slave lag to resolve */
+ /** @var integer Seconds to spend waiting on replica DB lag to resolve */
private $mWaitTimeout;
/** @var array LBFactory information */
private $mParentInfo;
/** @var bool|DatabaseBase Database connection that caused a problem */
private $mErrorConnection;
- /** @var integer The generic (not query grouped) slave index (of $mServers) */
+ /** @var integer The generic (not query grouped) replica DB index (of $mServers) */
private $mReadIndex;
/** @var bool|DBMasterPos False if not set */
private $mWaitForPos;
- /** @var bool Whether the generic reader fell back to a lagged slave */
- private $laggedSlaveMode = false;
- /** @var bool Whether the generic reader fell back to a lagged slave */
- private $slavesDownMode = false;
+ /** @var bool Whether the generic reader fell back to a lagged replica DB */
+ private $laggedReplicaMode = false;
+ /** @var bool Whether the generic reader fell back to a lagged replica DB */
+ private $allReplicasDownMode = false;
/** @var string The last DB selection or connection error */
private $mLastError = 'Unknown error';
/** @var string|bool Reason the LB is read-only or false if not */
/** @var integer Warn when this many connection are held */
const CONN_HELD_WARN_THRESHOLD = 10;
/** @var integer Default 'max lag' when unspecified */
- const MAX_LAG = 10;
- /** @var integer Max time to wait for a slave to catch up (e.g. ChronologyProtector) */
+ const MAX_LAG_DEFAULT = 10;
+ /** @var integer Max time to wait for a replica DB to catch up (e.g. ChronologyProtector) */
const POS_WAIT_TIMEOUT = 10;
/** @var integer Seconds to cache master server read-only status */
const TTL_CACHE_READONLY = 5;
* @param int $maxLag Restrict the maximum allowed lag to this many seconds
* @return bool|int|string
*/
- private function getRandomNonLagged( array $loads, $wiki = false, $maxLag = self::MAX_LAG ) {
+ private function getRandomNonLagged( array $loads, $wiki = false, $maxLag = INF ) {
$lags = $this->getLagTimes( $wiki );
# Unset excessively lagged servers
foreach ( $lags as $i => $lag ) {
if ( $i != 0 ) {
- $maxServerLag = $maxLag;
- if ( isset( $this->mServers[$i]['max lag'] ) ) {
- $maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
- }
+ # How much lag this server nominally is allowed to have
+ $maxServerLag = isset( $this->mServers[$i]['max lag'] )
+ ? $this->mServers[$i]['max lag']
+ : self::MAX_LAG_DEFAULT; // default
+ # Constrain that futher by $maxLag argument
+ $maxServerLag = min( $maxServerLag, $maxLag );
$host = $this->getServerName( $i );
- if ( $lag === false ) {
+ if ( $lag === false && !is_infinite( $maxServerLag ) ) {
wfDebugLog( 'replication', "Server $host (#$i) is not replicating?" );
unset( $loads[$i] );
} elseif ( $lag > $maxServerLag ) {
}
}
- # Find out if all the slaves with non-zero load are lagged
+ # Find out if all the replica DBs with non-zero load are lagged
$sum = 0;
foreach ( $loads as $load ) {
$sum += $load;
}
if ( $sum == 0 ) {
- # No appropriate DB servers except maybe the master and some slaves with zero load
+ # No appropriate DB servers except maybe the master and some replica DBs with zero load
# Do NOT use the master
# Instead, this function will return false, triggering read-only mode,
- # and a lagged slave will be used instead.
+ # and a lagged replica DB will be used instead.
return false;
}
}
/**
- * Get the index of the reader connection, which may be a slave
+ * Get the index of the reader connection, which may be a replica DB
* This takes into account load ratios and lag times. It should
* always return a consistent index during a given invocation
*
# Scale the configured load ratios according to the dynamic load (if the load monitor supports it)
$this->getLoadMonitor()->scaleLoads( $nonErrorLoads, $group, $wiki );
- $laggedSlaveMode = false;
+ $laggedReplicaMode = false;
# No server found yet
$i = false;
- $conn = false;
# First try quickly looking through the available servers for a server that
# meets our criteria
$currentLoads = $nonErrorLoads;
while ( count( $currentLoads ) ) {
- if ( $this->mAllowLagged || $laggedSlaveMode ) {
+ if ( $this->mAllowLagged || $laggedReplicaMode ) {
$i = ArrayUtils::pickRandom( $currentLoads );
} else {
$i = false;
$i = $this->getRandomNonLagged( $currentLoads, $wiki );
}
if ( $i === false && count( $currentLoads ) != 0 ) {
- # All slaves lagged. Switch to read-only mode
- wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
+ # All replica DBs lagged. Switch to read-only mode
+ wfDebugLog( 'replication', "All replica DBs lagged. Switch to read-only mode" );
$i = ArrayUtils::pickRandom( $currentLoads );
- $laggedSlaveMode = true;
+ $laggedReplicaMode = true;
}
}
}
if ( $i !== false ) {
- # Slave connection successful
- # Wait for the session master pos for a short time
+ # Replica DB connection successful.
+ # Wait for the session master pos for a short time.
if ( $this->mWaitForPos && $i > 0 ) {
- if ( !$this->doWait( $i ) ) {
- $this->mServers[$i]['slave pos'] = $conn->getSlavePos();
- }
+ $this->doWait( $i );
}
if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) {
$this->mReadIndex = $i;
- # Record if the generic reader index is in "lagged slave" mode
- if ( $laggedSlaveMode ) {
- $this->laggedSlaveMode = true;
+ # Record if the generic reader index is in "lagged replica DB" mode
+ if ( $laggedReplicaMode ) {
+ $this->laggedReplicaMode = true;
}
}
$serverName = $this->getServerName( $i );
/**
* Set the master wait position
- * If a DB_SLAVE connection has been opened already, waits
+ * If a DB_REPLICA connection has been opened already, waits
* Otherwise sets a variable telling it to wait if such a connection is opened
* @param DBMasterPos $pos
*/
if ( $i > 0 ) {
if ( !$this->doWait( $i ) ) {
- $this->mServers[$i]['slave pos'] = $this->getAnyOpenConnection( $i )->getSlavePos();
- $this->laggedSlaveMode = true;
+ $this->laggedReplicaMode = true;
}
}
}
/**
- * Set the master wait position and wait for a "generic" slave to catch up to it
+ * Set the master wait position and wait for a "generic" replica DB to catch up to it
*
* This can be used a faster proxy for waitForAll()
*
$i = $this->mReadIndex;
if ( $i <= 0 ) {
- // Pick a generic slave if there isn't one yet
+ // Pick a generic replica DB if there isn't one yet
$readLoads = $this->mLoads;
- unset( $readLoads[$this->getWriterIndex()] ); // slaves only
+ unset( $readLoads[$this->getWriterIndex()] ); // replica DBs only
$readLoads = array_filter( $readLoads ); // with non-zero load
$i = ArrayUtils::pickRandom( $readLoads );
}
}
/**
- * Set the master wait position and wait for ALL slaves to catch up to it
+ * Set the master wait position and wait for ALL replica DBs to catch up to it
* @param DBMasterPos $pos
* @param int $timeout Max seconds to wait; default is mWaitTimeout
* @return bool Success (able to connect and no timeouts reached)
}
/**
- * Wait for a given slave to catch up to the master pos stored in $this
+ * Wait for a given replica DB to catch up to the master pos stored in $this
* @param int $index Server index
* @param bool $open Check the server even if a new connection has to be made
* @param int $timeout Max seconds to wait; default is mWaitTimeout
$knownReachedPos = $this->srvCache->get( $key );
if ( $knownReachedPos && $knownReachedPos->hasReached( $this->mWaitForPos ) ) {
wfDebugLog( 'replication', __METHOD__ .
- ": slave $server known to be caught up (pos >= $knownReachedPos).\n" );
+ ": replica DB $server known to be caught up (pos >= $knownReachedPos).\n" );
return true;
}
}
}
- wfDebugLog( 'replication', __METHOD__ . ": Waiting for slave $server to catch up...\n" );
+ wfDebugLog( 'replication', __METHOD__ . ": Waiting for replica DB $server to catch up...\n" );
$timeout = $timeout ?: $this->mWaitTimeout;
$result = $conn->masterPosWait( $this->mWaitForPos, $timeout );
if ( $result == -1 || is_null( $result ) ) {
- // Timed out waiting for slave, use master instead
+ // Timed out waiting for replica DB, use master instead
$msg = __METHOD__ . ": Timed out waiting on $server pos {$this->mWaitForPos}";
wfDebugLog( 'replication', "$msg\n" );
wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
}
# Operation-based index
- if ( $i == DB_SLAVE ) {
+ if ( $i == DB_REPLICA ) {
$this->mLastError = 'Unknown error'; // reset error string
# Try the general server pool if $groups are unavailable.
$i = in_array( false, $groups, true )
: $this->getReaderIndex( false, $wiki );
# Couldn't find a working server in getReaderIndex()?
if ( $i === false ) {
- $this->mLastError = 'No working slave server: ' . $this->mLastError;
+ $this->mLastError = 'No working replica DB server: ' . $this->mLastError;
return $this->reportConnectionError();
}
/**
* This can happen in code like:
* foreach ( $dbs as $db ) {
- * $conn = $lb->getConnection( DB_SLAVE, [], $db );
+ * $conn = $lb->getConnection( DB_REPLICA, [], $db );
* ...
* $lb->reuseConnection( $conn );
* }
* @return mixed
*/
public function getMasterPos() {
- # If this entire request was served from a slave without opening a connection to the
- # master (however unlikely that may be), then we can fetch the position from the slave.
+ # If this entire request was served from a replica DB without opening a connection to the
+ # master (however unlikely that may be), then we can fetch the position from the replica DB.
$masterConn = $this->getAnyOpenConnection( 0 );
if ( !$masterConn ) {
$serverCount = count( $this->mServers );
/**
* @note This method will trigger a DB connection if not yet done
- *
* @param string|bool $wiki Wiki ID, or false for the current wiki
* @return bool Whether the generic connection for reads is highly "lagged"
*/
- public function getLaggedSlaveMode( $wiki = false ) {
+ public function getLaggedReplicaMode( $wiki = false ) {
// No-op if there is only one DB (also avoids recursion)
- if ( !$this->laggedSlaveMode && $this->getServerCount() > 1 ) {
+ if ( !$this->laggedReplicaMode && $this->getServerCount() > 1 ) {
try {
- // See if laggedSlaveMode gets set
- $conn = $this->getConnection( DB_SLAVE, false, $wiki );
+ // See if laggedReplicaMode gets set
+ $conn = $this->getConnection( DB_REPLICA, false, $wiki );
$this->reuseConnection( $conn );
} catch ( DBConnectionError $e ) {
// Avoid expensive re-connect attempts and failures
- $this->slavesDownMode = true;
- $this->laggedSlaveMode = true;
+ $this->allReplicasDownMode = true;
+ $this->laggedReplicaMode = true;
}
}
- return $this->laggedSlaveMode;
+ return $this->laggedReplicaMode;
+ }
+
+ /**
+ * @param bool $wiki
+ * @return bool
+ * @deprecated 1.28; use getLaggedReplicaMode()
+ */
+ public function getLaggedSlaveMode( $wiki = false ) {
+ return $this->getLaggedReplicaMode( $wiki );
}
/**
* @note This method will never cause a new DB connection
* @return bool Whether any generic connection used for reads was highly "lagged"
+ * @since 1.28
+ */
+ public function laggedReplicaUsed() {
+ return $this->laggedReplicaMode;
+ }
+
+ /**
+ * @return bool
* @since 1.27
+ * @deprecated Since 1.28; use laggedReplicaUsed()
*/
public function laggedSlaveUsed() {
- return $this->laggedSlaveMode;
+ return $this->laggedReplicaUsed();
}
/**
public function getReadOnlyReason( $wiki = false, DatabaseBase $conn = null ) {
if ( $this->readOnlyReason !== false ) {
return $this->readOnlyReason;
- } elseif ( $this->getLaggedSlaveMode( $wiki ) ) {
- if ( $this->slavesDownMode ) {
+ } elseif ( $this->getLaggedReplicaMode( $wiki ) ) {
+ if ( $this->allReplicasDownMode ) {
return 'The database has been automatically locked ' .
- 'until the slave database servers become available';
+ 'until the replica database servers become available';
} else {
return 'The database has been automatically locked ' .
- 'while the slave database servers catch up to the master.';
+ 'while the replica database servers catch up to the master.';
}
} elseif ( $this->masterRunningReadOnly( $wiki, $conn ) ) {
return 'The database master is running in read-only mode.';
}
/**
- * Get the hostname and lag time of the most-lagged slave
+ * Get the hostname and lag time of the most-lagged replica DB
*
* This is useful for maintenance scripts that need to throttle their updates.
- * May attempt to open connections to slaves on the default DB. If there is
+ * May attempt to open connections to replica DBs on the default DB. If there is
* no lag, the maximum lag will be reported as -1.
*
* @param bool|string $wiki Wiki ID, or false for the default database
}
/**
- * Wait for a slave DB to reach a specified master position
+ * Wait for a replica DB to reach a specified master position
*
* This will connect to the master to get an accurate position if $pos is not given
*
- * @param IDatabase $conn Slave DB
+ * @param IDatabase $conn Replica DB
* @param DBMasterPos|bool $pos Master position; default: current position
* @param integer $timeout Timeout in seconds
* @return bool Success
* @since 1.27
*/
public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
- if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'slave' ) ) {
- return true; // server is not a slave DB
+ if ( $this->getServerCount() == 1 || !$conn->getLBInfo( 'replica' ) ) {
+ return true; // server is not a replica DB
}
$pos = $pos ?: $this->getConnection( DB_MASTER )->getMasterPos();
*/
public static function cacheUpdate( $dbw ) {
global $wgActiveUserDays;
- $dbr = wfGetDB( DB_SLAVE, 'vslow' );
+ $dbr = wfGetDB( DB_REPLICA, 'vslow' );
# Get non-bot users than did some recent action other than making accounts.
# If account creation is included, the number gets inflated ~20+ fold on enwiki.
$activeUsers = $dbr->selectField(
*/
public function deletedLink( $id ) {
if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'archive', '*',
[ 'ar_rev_id' => $id ],
__METHOD__ );
RecentChange::isInRCLifespan( $this->mNewRev->getTimestamp(), 21600 )
) {
// Look for an unpatrolled change corresponding to this diff
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$change = RecentChange::newFromConds(
[
'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
}
/**
- * Add style sheets and supporting JS for diff display.
+ * Add style sheets for diff display.
*/
public function showDiffStyle() {
- $this->getOutput()->addModuleStyles( 'mediawiki.action.history.diff' );
+ $this->getOutput()->addModuleStyles( 'mediawiki.diff.styles' );
}
/**
}
// Load tags information for both revisions
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->mOldid !== false ) {
$this->mOldTags = $dbr->selectField(
'tag_summary',
}
/**
- * Get a slave database connection for the specified cluster
+ * Get a replica DB connection for the specified cluster
*
* @param string $cluster Cluster name
* @return IDatabase
wfDebug( "writable external store\n" );
}
- $db = $lb->getConnection( DB_SLAVE, [], $wiki );
+ $db = $lb->getConnection( DB_REPLICA, [], $wiki );
$db->clearFlag( DBO_TRX ); // sanity
return $db;
}
/**
- * Helper function for self::batchFetchBlobs for merging master/slave results
+ * Helper function for self::batchFetchBlobs for merging master/replica DB results
* @param array &$ret Current self::batchFetchBlobs return value
* @param array &$ids Map from blob_id to requested itemIDs
* @param mixed $res DB result from Database::select
*
* a) Create a new file in storage with the contents of a string
* @code
- * array(
+ * [
* 'op' => 'create',
* 'dst' => <storage path>,
* 'content' => <string of new file contents>,
* 'overwrite' => <boolean>,
* 'overwriteSame' => <boolean>,
* 'headers' => <HTTP header name/value map> # since 1.21
- * );
+ * ]
* @endcode
*
* b) Copy a file system file into storage
* @code
- * array(
+ * [
* 'op' => 'store',
* 'src' => <file system path, FSFile, or TempFSFile>,
* 'dst' => <storage path>,
* 'overwrite' => <boolean>,
* 'overwriteSame' => <boolean>,
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* c) Copy a file within storage
* @code
- * array(
+ * [
* 'op' => 'copy',
* 'src' => <storage path>,
* 'dst' => <storage path>,
* 'overwriteSame' => <boolean>,
* 'ignoreMissingSource' => <boolean>, # since 1.21
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* d) Move a file within storage
* @code
- * array(
+ * [
* 'op' => 'move',
* 'src' => <storage path>,
* 'dst' => <storage path>,
* 'overwriteSame' => <boolean>,
* 'ignoreMissingSource' => <boolean>, # since 1.21
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* e) Delete a file within storage
* @code
- * array(
+ * [
* 'op' => 'delete',
* 'src' => <storage path>,
* 'ignoreMissingSource' => <boolean>
- * )
+ * ]
* @endcode
*
* f) Update metadata for a file within storage
* @code
- * array(
+ * [
* 'op' => 'describe',
* 'src' => <storage path>,
* 'headers' => <HTTP header name/value map>
- * )
+ * ]
* @endcode
*
* g) Do nothing (no-op)
* @code
- * array(
+ * [
* 'op' => 'null',
- * )
+ * ]
* @endcode
*
* Boolean flags for operations (operation-specific):
*
* a) Create a new file in storage with the contents of a string
* @code
- * array(
+ * [
* 'op' => 'create',
* 'dst' => <storage path>,
* 'content' => <string of new file contents>,
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* b) Copy a file system file into storage
* @code
- * array(
+ * [
* 'op' => 'store',
* 'src' => <file system path, FSFile, or TempFSFile>,
* 'dst' => <storage path>,
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* c) Copy a file within storage
* @code
- * array(
+ * [
* 'op' => 'copy',
* 'src' => <storage path>,
* 'dst' => <storage path>,
* 'ignoreMissingSource' => <boolean>, # since 1.21
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* d) Move a file within storage
* @code
- * array(
+ * [
* 'op' => 'move',
* 'src' => <storage path>,
* 'dst' => <storage path>,
* 'ignoreMissingSource' => <boolean>, # since 1.21
* 'headers' => <HTTP header name/value map> # since 1.21
- * )
+ * ]
* @endcode
*
* e) Delete a file within storage
* @code
- * array(
+ * [
* 'op' => 'delete',
* 'src' => <storage path>,
* 'ignoreMissingSource' => <boolean>
- * )
+ * ]
* @endcode
*
* f) Update metadata for a file within storage
* @code
- * array(
+ * [
* 'op' => 'describe',
* 'src' => <storage path>,
* 'headers' => <HTTP header name/value map>
- * )
+ * ]
* @endcode
*
* g) Do nothing (no-op)
* @code
- * array(
+ * [
* 'op' => 'null',
- * )
+ * ]
* @endcode
*
* @par Boolean flags for operations (operation-specific):
* @return array Translated paths in same order
*/
public function getBackendPaths( array $paths, $latest = true ) {
- $db = $this->getDB( $latest ? DB_MASTER : DB_SLAVE );
+ $db = $this->getDB( $latest ? DB_MASTER : DB_REPLICA );
// @TODO: batching
$resolved = [];
* @param array $items An array of titles, or an array of findFile() options with
* the "title" option giving the title. Example:
*
- * $findItem = array( 'title' => $title, 'private' => true );
- * $findBatch = array( $findItem );
+ * $findItem = [ 'title' => $title, 'private' => true ];
+ * $findBatch = [ $findItem ];
* $repo->findFiles( $findBatch );
*
* No title should appear in $items twice, as the result use titles as keys
*
* Example config:
*
- * $wgForeignFileRepos[] = array(
+ * $wgForeignFileRepos[] = [
* 'class' => 'ForeignAPIRepo',
* 'name' => 'shared',
* 'apibase' => 'https://en.wikipedia.org/w/api.php',
* 'fetchDescription' => true, // Optional
* 'descriptionCacheExpiry' => 3600,
- * );
+ * ];
*
* @ingroup FileRepo
*/
* @return IDatabase
*/
function getSlaveDB() {
- return wfGetDB( DB_SLAVE, [], $this->wiki );
+ return wfGetDB( DB_REPLICA, [], $this->wiki );
}
/**
}
/**
- * Get a connection to the slave DB
+ * Get a connection to the replica DB
* @return DatabaseBase
*/
function getSlaveDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
}
/**
- * Get a callback to get a DB handle given an index (DB_SLAVE/DB_MASTER)
+ * Get a callback to get a DB handle given an index (DB_REPLICA/DB_MASTER)
* @return Closure
*/
protected function getDBFactory() {
if ( !$this->title || $this->title->getNamespace() == NS_FILE ) {
$this->dataLoaded = true; // set it here, to have also true on miss
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow(
'filearchive',
self::selectFields(),
// Update article count statistics (T42009)
// The normal counting logic in WikiPage->doEditUpdates() is designed for
// one-revision-at-a-time editing, not bulk imports. In this situation it
- // suffers from issues of slave lag. We let WikiPage handle the total page
+ // suffers from issues of replica DB lag. We let WikiPage handle the total page
// and revision count, and we implement our own custom logic for the
// article (content page) count.
$page = WikiPage::factory( $title );
"config-mysql-myisam": "MyISAM",
"config-mysql-myisam-dep": "<strong>Warnung:</strong> Es wurde MyISAM als Speichersubsystem für das Datenbanksystem MySQL ausgewählt. Aus folgenden Gründen wird es nicht für den Einsatz mit MediaWiki empfohlen:\n* Es unterstützt aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen.\n* Es ist anfälliger für Datenprobleme.\n* Es wird von MediaWiki nicht immer adäquat unterstützt.\n\nSofern die vorhandene MySQL-Installation das Speichersubsystem InnoDB unterstützt, wird deren Verwendung eindringlich empfohlen.\nSofern sie es nicht unterstützt, sollte nunmehr eine entsprechende Aktualisierung in Erwägung gezogen werden.",
"config-mysql-only-myisam-dep": "<strong>Warnung:</strong> MyISAM ist das einzige verfügbare Speichersubsystem für das Datenbanksystem MySQL auf diesem Server. Es wird nicht für die Verwendung mit MediaWiki empfohlen, da es\n* aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen unterstützt,\n* anfälliger für Datenprobleme ist und\n* von MediaWiki nicht immer adäquat unterstützt wird.\n\nDeine MySQL-Installation unterstützt nicht das Speichersubsystem InnoDB. Eine Aktualisierung wird nunmehr empfohlen.",
- "config-mysql-engine-help": "'''InnoDB''' ist fast immer die bessere Wahl, da es gleichzeitige Zugriffe gut unterstützt.\n\n'''MyISAM''' ist in Einzelnutzerumgebungen sowie bei schreibgeschützten Wikis schneller.\nBei MyISAM-Datenbanken treten tendenziell häufiger Fehler auf als bei InnoDB-Datenbanken.",
+ "config-mysql-engine-help": "<strong>InnoDB</strong> als Speichersubsystem für das Datenbanksystem MySQL ist fast immer die bessere Wahl, da es gleichzeitige Zugriffe gut unterstützt.\n\n<strong>MyISAM</strong> als Speichersubsystem für das Datenbanksystem MySQL ist hingegen in Einzelnutzerumgebungen oder bei schreibgeschützten Wikis schneller.\nDatenbanken, die MyISAM verwenden, sind indes tendenziell fehleranfälliger als solche, die InnoDB verwenden.",
"config-mysql-charset": "Datenbankzeichensatz:",
"config-mysql-binary": "binär",
"config-mysql-utf8": "UTF-8",
"config-type-sqlite": "SQLite",
"config-type-oracle": "Oracle",
"config-type-mssql": "Microsoft SQL Server",
- "config-support-info": "MediaWiki supporte ces systèmes de bases de données :\n\n$1\n\nSi vous ne voyez pas le système de base de données que vous essayez d'utiliser ci-dessous, alors suivez les instructions ci-dessus (voir liens) pour activer le support.",
+ "config-support-info": "MediaWiki prend en charge ces systèmes de bases de données :\n\n$1\n\nSi vous ne voyez pas le système de base de données que vous essayez d’utiliser ci-dessous, alors suivez les instructions ci-dessus (voir liens) pour activer la prise en charge.",
"config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mariadb-url}} MariaDB] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec le support MySQL])",
"config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire et ''open source'' qui peut être une alternative à MySQL. Son support peut contenir quelques bogues mineurs et n'est pas recommandé dans un environnement de production. ([http://www.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec le support de PostgreSQL])",
- "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien supporté. ([http://www.php.net/manual/en/pdo.installation.php Comment compiler PHP avec le support de SQLite], en utilisant PDO)",
+ "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien pris en charge. ([http://www.php.net/manual/fr/pdo.installation.php Comment compiler PHP avec la prise en charge de SQLite], en utilisant PDO)",
"config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] est un système commercial de gestion de base de données d’entreprise. ([http://www.php.net/manual/en/oci8.installation.php Comment compiler PHP avec le support OCI8])",
"config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] est une base de données commerciale d’entreprise pour Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Comment compiler PHP avec le support de SQLSRV])",
"config-header-mysql": "Paramètres de MySQL",
"config-mysql-engine": "Moteur de stockage :",
"config-mysql-innodb": "InnoDB",
"config-mysql-myisam": "MyISAM",
- "config-mysql-myisam-dep": "''' Avertissement ''': vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n'est pas recommandé pour une utilisation avec MediaWiki, parce que:\n * il supporte à peine la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le codebase MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL supporte InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne supporte pas les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
- "config-mysql-only-myisam-dep": "'''Attention :''' MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il supporte très peu les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne supporte pas InnoDB ; il est peut-être temps de la mettre à jour.",
- "config-mysql-engine-help": "'''InnoDB''' est presque toujours la meilleure option, car il supporte bien les accès concurrents.\n\n'''MyISAM''' peut être plus rapide dans les installations monoposte ou en lecture seule. \nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d'InnoDB.",
+ "config-mysql-myisam-dep": "''' Avertissement ''': vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n’est pas recommandé pour une utilisation avec MediaWiki, parce que :\n * il prend à peine en charge la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le code de base MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL prenden charge InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne prend pas en charge les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
+ "config-mysql-only-myisam-dep": "'''Attention :''' MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il prend très peu en charge les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne prend pas en charge InnoDB ; il est peut-être temps de la mettre à jour.",
+ "config-mysql-engine-help": "'''InnoDB''' est presque toujours la meilleure option, car il prend bien en charge les accès concurrents.\n\n'''MyISAM''' peut être plus rapide dans les installations monoposte ou en lecture seule.\nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d’InnoDB.",
"config-mysql-charset": "Jeu de caractères de la base de données :",
"config-mysql-binary": "Binaire",
"config-mysql-utf8": "UTF-8",
"config-help": "aide",
"config-help-tooltip": "cliquer pour agrandir",
"config-nofile": "Le fichier « $1 » est introuvable. A-t-il été supprimé ?",
- "config-extension-link": "Saviez-vous que votre wiki supporte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions des extensions] ?\n\nVous pouvez consulter les [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions par catégorie] ou la [https://www.mediawiki.org/wiki/Extension_Matrix matrice des extensions] pour voir la liste complète des extensions.",
+ "config-extension-link": "Saviez-vous que votre wiki prend en charge [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions des extensions] ?\n\nVous pouvez consulter les [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions par catégorie] ou la [https://www.mediawiki.org/wiki/Extension_Matrix matrice des extensions] pour voir la liste complète des extensions.",
"mainpagetext": "<strong>MediaWiki a été installé.</strong>",
"mainpagedocfooter": "Consultez le [https://meta.wikimedia.org/wiki/Help:Contents/fr Guide de l’utilisateur] pour plus d’informations sur l’utilisation de ce logiciel de wiki.\n\n== Pour démarrer ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Liste des paramètres de configuration]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/fr Questions courantes sur MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Liste de discussion sur les distributions de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Adaptez MediaWiki dans votre langue]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Apprendre comment lutter contre le pourriel dans votre wiki]"
}
* and tree storage backends (SQL, CDB, and plain PHP arrays).
*
* All information is loaded on creation when called by $this->fetch( $prefix ).
- * All work is done on slave, because this should *never* change (except during
+ * All work is done on replica DB, because this should *never* change (except during
* schema updates etc, which aren't wiki-related)
*
* @since 1.28
$this->objectCache->makeKey( 'interwiki', $prefix ),
$this->objectCacheExpiry,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $prefix ) {
- $dbr = wfGetDB( DB_SLAVE ); // TODO: inject LoadBalancer
+ $dbr = wfGetDB( DB_REPLICA ); // TODO: inject LoadBalancer
$setOpts += Database::getCacheSetOptions( $dbr );
* @return array[] Interwiki rows
*/
private function getAllPrefixesDB( $local ) {
- $db = wfGetDB( DB_SLAVE ); // TODO: inject DB LoadBalancer
+ $db = wfGetDB( DB_REPLICA ); // TODO: inject DB LoadBalancer
$where = [];
}
/**
- * Wait for any slaves or backup servers to catch up.
+ * Wait for any replica DBs or backup servers to catch up.
*
* This does nothing for certain queue classes.
*
}
// Build the full list of job rows to insert
$rows = array_merge( $rowList, array_values( $rowSet ) );
- // Insert the job rows in chunks to avoid slave lag...
+ // Insert the job rows in chunks to avoid replica DB lag...
foreach ( array_chunk( $rows, 50 ) as $rowBatch ) {
$dbw->insert( 'job', $rowBatch, $method );
}
*/
protected function getSlaveDB() {
try {
- return $this->getDB( DB_SLAVE );
+ return $this->getDB( DB_REPLICA );
} catch ( DBConnectionError $e ) {
throw new JobQueueConnectionError( "DBConnectionError:" . $e->getMessage() );
}
}
/**
- * @param int $index (DB_SLAVE/DB_MASTER)
+ * @param int $index (DB_REPLICA/DB_MASTER)
* @return DBConnRef
*/
protected function getDB( $index ) {
}
/**
- * Wait for any slaves or backup queue servers to catch up.
+ * Wait for any replica DBs or backup queue servers to catch up.
*
* This does nothing for certain queue classes.
*
protected $logger;
const MAX_ALLOWED_LAG = 3; // abort if more than this much DB lag is present
- const LAG_CHECK_PERIOD = 1.0; // check slave lag this many seconds
+ const LAG_CHECK_PERIOD = 1.0; // check replica DB lag this many seconds
const ERROR_BACKOFF_TTL = 1; // seconds to back off a queue due to errors
/**
// This check should not block as we want to try other wiki queues.
list( , $maxLag ) = wfGetLB( wfWikiID() )->getMaxLag();
if ( $maxLag >= self::MAX_ALLOWED_LAG ) {
- $response['reached'] = 'slave-lag-limit';
+ $response['reached'] = 'replica-lag-limit';
return $response;
}
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$lbFactory->commitAll( __METHOD__ );
- // Catch huge single updates that lead to slave lag
+ // Catch huge single updates that lead to replica DB lag
$trxProfiler = Profiler::instance()->getTransactionProfiler();
$trxProfiler->setLogger( LoggerFactory::getInstance( 'DBPerformance' ) );
$trxProfiler->setExpectations( $wgTrxProfilerLimits['JobRunner'], __METHOD__ );
$jobsPopped = 0;
$timeMsTotal = 0;
$startTime = microtime( true ); // time since jobs started running
- $lastCheckTime = 1; // timestamp of last slave check
+ $lastCheckTime = 1; // timestamp of last replica DB check
do {
// Sync the persistent backoffs with concurrent runners
$backoffs = $this->syncBackoffDeltas( $backoffs, $backoffDeltas, $wait );
break;
}
- // Don't let any of the main DB slaves get backed up.
+ // Don't let any of the main DB replica DBs get backed up.
// This only waits for so long before exiting and letting
// other wikis in the farm (on different masters) get a chance.
$timePassed = microtime( true ) - $lastCheckTime;
'timeout' => self::MAX_ALLOWED_LAG
] );
} catch ( DBReplicationWaitError $e ) {
- $response['reached'] = 'slave-lag-limit';
+ $response['reached'] = 'replica-lag-limit';
break;
}
$lastCheckTime = microtime( true );
}
- // Don't let any queue slaves/backups fall behind
+ // Don't let any queue replica DBs/backups fall behind
if ( $jobsPopped > 0 && ( $jobsPopped % 100 ) == 0 ) {
$group->waitForBackups();
}
// Commit all outstanding connections that are in a transaction
// to get a fresh repeatable read snapshot on every connection.
- // Note that jobs are still responsible for handling slave lag.
+ // Note that jobs are still responsible for handling replica DB lag.
$lbFactory->flushReplicaSnapshots( __METHOD__ );
// Clear out title cache data from prior snapshots
LinkCache::singleton()->clear();
/**
* Issue a commit on all masters who are currently in a transaction and have
* made changes to the database. It also supports sometimes waiting for the
- * local wiki's slaves to catch up. See the documentation for
+ * local wiki's replica DBs to catch up. See the documentation for
* $wgJobSerialCommitThreshold for more.
*
* @param Job $job
$dbwSerial = false;
}
} else {
- // There are no slaves or writes are all to foreign DB (we don't handle that)
+ // There are no replica DBs or writes are all to foreign DB (we don't handle that)
$dbwSerial = false;
}
// This will trigger a rollback in the main loop
throw new DBError( $dbwSerial, "Timed out waiting on commit queue." );
}
- // Wait for the slave DBs to catch up
+ // Wait for the replica DBs to catch up
$pos = $lb->getMasterPos();
if ( $pos ) {
$lb->waitForAll( $pos );
return false;
}
- $dbr = wfGetDB( DB_SLAVE, [ 'recentchanges' ] );
- // Wait till the slave is caught up so that jobs for this page see each others' changes
+ $dbr = wfGetDB( DB_REPLICA, [ 'recentchanges' ] );
+ // Wait till the replica DB is caught up so that jobs for this page see each others' changes
if ( !wfGetLB()->safeWaitForMasterPos( $dbr ) ) {
- $this->setLastError( "Timed out while waiting for slave to catch up" );
+ $this->setLastError( "Timed out while waiting for replica DB to catch up" );
return false;
}
// Clear any stale REPEATABLE-READ snapshot
* @code
* $ php maintenance/eval.php
* > $queue = JobQueueGroup::singleton();
- * > $job = new NullJob( Title::newMainPage(), array( 'lives' => 10 ) );
+ * > $job = new NullJob( Title::newMainPage(), [ 'lives' => 10 ] );
* > $queue->push( $job );
* @endcode
* You can then confirm the job has been enqueued by using the showJobs.php
);
if ( $rcIds ) {
$dbw->delete( 'recentchanges', [ 'rc_id' => $rcIds ], __METHOD__ );
- // There might be more, so try waiting for slaves
+ // There might be more, so try waiting for replica DBs
try {
$factory->commitAndWaitForReplication(
__METHOD__, $ticket, [ 'timeout' => 3 ]
const PARSE_THRESHOLD_SEC = 1.0;
/** @var integer Lag safety margin when comparing root job times to last-refresh times */
const CLOCK_FUDGE = 10;
- /** @var integer How many seconds to wait for slaves to catch up */
+ /** @var integer How many seconds to wait for replica DBs to catch up */
const LAG_WAIT_TIMEOUT = 15;
function __construct( Title $title, array $params ) {
// Job to update all (or a range of) backlink pages for a page
if ( !empty( $this->params['recursive'] ) ) {
- // When the base job branches, wait for the slaves to catch up to the master.
+ // When the base job branches, wait for the replica DBs to catch up to the master.
// From then on, we know that any template changes at the time the base job was
// enqueued will be reflected in backlink page parses when the leaf jobs run.
if ( !isset( $params['range'] ) ) {
$skewedTimestamp = $this->params['rootJobTimestamp'];
if ( $opportunistic ) {
- // Neither clock skew nor DB snapshot/slave lag matter much for such
+ // Neither clock skew nor DB snapshot/replica DB lag matter much for such
// updates; focus on reusing the (often recently updated) cache
} else {
// For transclusion updates, the template changes must be reflected
* @since 1.26
*/
class SamplingStatsdClient extends StatsdClient {
+ protected $samplingRates = [];
+
+ /**
+ * Sampling rates as an associative array of patterns and rates.
+ * Patterns are Unix shell patterns (e.g. 'MediaWiki.api.*').
+ * Rates are sampling probabilities (e.g. 0.1 means 1 in 10 events are sampled).
+ * @param array $samplingRates
+ * @since 1.28
+ */
+ public function setSamplingRates( array $samplingRates ) {
+ $this->samplingRates = $samplingRates;
+ }
+
/**
* Sets sampling rate for all items in $data.
* The sample rate specified in a StatsdData entity overrides the sample rate specified here.
* {@inheritDoc}
*/
public function appendSampleRate( $data, $sampleRate = 1 ) {
- if ( $sampleRate < 1 ) {
- array_walk( $data, function( $item ) use ( $sampleRate ) {
+ $samplingRates = $this->samplingRates;
+ if ( !$samplingRates && $sampleRate !== 1 ) {
+ $samplingRates = [ '*' => $sampleRate ];
+ }
+ if ( $samplingRates ) {
+ array_walk( $data, function( $item ) use ( $samplingRates ) {
/** @var $item StatsdData */
- if ( $item->getSampleRate() === 1 ) {
- $item->setSampleRate( $sampleRate );
+ foreach ( $samplingRates as $pattern => $rate ) {
+ if ( fnmatch( $pattern, $item->getKey(), FNM_NOESCAPE ) ) {
+ $item->setSampleRate( $item->getSampleRate() * $rate );
+ break;
+ }
}
} );
}
}
// add sampling
- if ( $sampleRate < 1 ) {
- $data = $this->appendSampleRate( $data, $sampleRate );
- }
+ $data = $this->appendSampleRate( $data, $sampleRate );
$data = $this->sampleData( $data );
$data = array_map( 'strval', $data );
* @param array $params Parameters for HashBagOStuff
*/
function __construct( BagOStuff $backend, $params = [] ) {
+ unset( $params['reportDupes'] ); // useless here
+
parent::__construct( $params );
$this->backend = $backend;
/**
* A cache class that directs writes to one set of servers and reads to
- * another. This assumes that the servers used for reads are setup to slave
+ * another. This assumes that the servers used for reads are setup to replica DB
* those that writes go to. This can easily be used with redis for example.
*
* In the WAN scenario (e.g. multi-datacenter case), this is useful when
* - writeFactory : ObjectFactory::getObjectFromSpec array yeilding BagOStuff.
* This object will be used for writes (e.g. the master DB).
* - readFactory : ObjectFactory::getObjectFromSpec array yeilding BagOStuff.
- * This object will be used for reads (e.g. a slave DB).
+ * This object will be used for reads (e.g. a replica DB).
*
* @param array $params
* @throws InvalidArgumentException
__METHOD__ . ': the "readFactory" parameter is required' );
}
+ $opts = [ 'reportDupes' => false ]; // redundant
$this->writeStore = ( $params['writeFactory'] instanceof BagOStuff )
? $params['writeFactory']
- : ObjectFactory::getObjectFromSpec( $params['writeFactory'] );
+ : ObjectFactory::getObjectFromSpec( $opts + $params['writeFactory'] );
$this->readStore = ( $params['readFactory'] instanceof BagOStuff )
? $params['readFactory']
- : ObjectFactory::getObjectFromSpec( $params['readFactory'] );
+ : ObjectFactory::getObjectFromSpec( $opts + $params['readFactory'] );
$this->attrMap = $this->mergeFlagMaps( [ $this->readStore, $this->writeStore ] );
}
*
* Example usage:
* @code
- * $dbr = wfGetDB( DB_SLAVE );
+ * $dbr = wfGetDB( DB_REPLICA );
* $setOpts = Database::getCacheSetOptions( $dbr );
* // Fetch the row from the DB
* $row = $dbr->selectRow( ... );
* @param integer $ttl Seconds to live. Special values are:
* - WANObjectCache::TTL_INDEFINITE: Cache forever
* @param array $opts Options map:
- * - lag : Seconds of slave lag. Typically, this is either the slave lag
- * before the data was read or, if applicable, the slave lag before
+ * - lag : Seconds of replica DB lag. Typically, this is either the replica DB lag
+ * before the data was read or, if applicable, the replica DB lag before
* the snapshot-isolated transaction the data was read from started.
* Default: 0 seconds
* - since : UNIX timestamp of the data in $value. Typically, this is either
* Keys using it via get(), getMulti(), or getWithSetCallback() will
* be invalidated. It is treated as being HOLDOFF_TTL seconds in the future
* by those methods to avoid race conditions where dependent keys get updated
- * with stale values (e.g. from a DB slave).
+ * with stale values (e.g. from a DB replica DB).
*
* This is typically useful for keys with hardcoded names or in some cases
* dynamically generated names where a low number of combinations exist.
* $cache::TTL_MINUTE,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return $dbr->selectRow( ... );
* $cache::TTL_DAY,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return CatConfig::newFromRow( $dbr->selectRow( ... ) );
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
* // Determine new value from the DB
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* return CatState::newFromResults( $dbr->select( ... ) );
* 10,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
- * $dbr = wfGetDB( DB_SLAVE );
- * // Account for any snapshot/slave lag
+ * $dbr = wfGetDB( DB_REPLICA );
+ * // Account for any snapshot/replica DB lag
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* // Start off with the last cached list
* - pcTTL: Process cache the value in this PHP instance for this many seconds. This avoids
* network I/O when a key is read several times. This will not cache when the callback
* returns false, however. Note that any purges will not be seen while process cached;
- * since the callback should use slave DBs and they may be lagged or have snapshot
+ * since the callback should use replica DBs and they may be lagged or have snapshot
* isolation anyway, this should not typically matter.
* Default: WANObjectCache::TTL_UNCACHEABLE.
* - version: Integer version number. This allows for callers to make breaking changes to
*
* @param int $newId Id of the log entry.
* @param string $to One of: rcandudp (default), rc, udp
- * @return RecentChange|null
*/
public function publish( $newId, $to = 'rcandudp' ) {
- $log = new LogPage( $this->getType() );
- if ( $log->isRestricted() ) {
- return null;
- }
-
- $rc = $this->getRecentChange( $newId );
-
- if ( $to === 'rc' || $to === 'rcandudp' ) {
- $rc->save( 'pleasedontudp' );
- }
-
- if ( $to === 'udp' || $to === 'rcandudp' ) {
- $rc->notifyRCFeeds();
- }
-
- // Log the autopatrol if the log entry is patrollable
- if ( $this->getIsPatrollable() &&
- $rc->getAttribute( 'rc_patrolled' ) === 1 ) {
- PatrolLog::record( $rc, true, $this->getPerformer() );
- }
-
- // Add change tags to the log entry and (if applicable) the associated revision
- $tags = $this->getTags();
- if ( !is_null( $tags ) ) {
- $rcId = $rc->getAttribute( 'rc_id' );
- $revId = $this->getAssociatedRevId(); // Use null if $revId is 0
- ChangeTags::addTags( $tags, $rcId, $revId > 0 ? $revId : null, $newId );
- }
-
- return $rc;
+ DeferredUpdates::addCallableUpdate(
+ function () use ( $newId, $to ) {
+ $log = new LogPage( $this->getType() );
+ if ( !$log->isRestricted() ) {
+ $rc = $this->getRecentChange( $newId );
+
+ if ( $to === 'rc' || $to === 'rcandudp' ) {
+ $rc->save( 'pleasedontudp' );
+ }
+
+ if ( $to === 'udp' || $to === 'rcandudp' ) {
+ $rc->notifyRCFeeds();
+ }
+
+ // Log the autopatrol if the log entry is patrollable
+ if ( $this->getIsPatrollable() &&
+ $rc->getAttribute( 'rc_patrolled' ) === 1
+ ) {
+ PatrolLog::record( $rc, true, $this->getPerformer() );
+ }
+
+ // Add change tags to the log entry and (if applicable) the associated revision
+ $tags = $this->getTags();
+ if ( !is_null( $tags ) ) {
+ $rcId = $rc->getAttribute( 'rc_id' );
+ $revId = $this->getAssociatedRevId(); // Use null if $revId is 0
+ ChangeTags::addTags( $tags, $rcId, $revId > 0 ? $revId : null, $newId );
+ }
+ }
+ },
+ DeferredUpdates::POSTSEND,
+ wfGetDB( DB_MASTER )
+ );
}
public function getType() {
$this->getDateCond( $year, $month );
$this->mTagFilter = $tagFilter;
- $this->mDb = wfGetDB( DB_SLAVE, 'logpager' );
+ $this->mDb = wfGetDB( DB_REPLICA, 'logpager' );
}
public function getDefaultQuery() {
* Purpose: Ephemeral global storage.
* Stored centrally within the primary data-center.
* Changes are applied there first and replicated to other DCs (best-effort).
- * To retrieve the latest value (e.g. not from a slave), use BagOStuff::READ_LATEST.
+ * To retrieve the latest value (e.g. not from a replica DB), use BagOStuff::READ_LATEST.
* This store may be subject to LRU style evictions.
*
* - ObjectCache::getInstance( $cacheType )
try {
if ( $this->getMasterLinkStatus( $conn ) === 'down' ) {
// If the master cannot be reached, fail-over to the next server.
- // If masters are in data-center A, and slaves in data-center B,
+ // If masters are in data-center A, and replica DBs in data-center B,
// this helps avoid the case were fail-over happens in A but not
// to the corresponding server in B (e.g. read/write mismatch).
continue;
}
/**
- * Check the master link status of a Redis server that is configured as a slave.
+ * Check the master link status of a Redis server that is configured as a replica DB.
* @param RedisConnRef $conn
* @return string|null Master link status (either 'up' or 'down'), or null
- * if the server is not a slave.
+ * if the server is not a replica DB.
*/
protected function getMasterLinkStatus( RedisConnRef $conn ) {
$info = $conn->info();
/** @var string */
protected $tableName = 'objectcache';
/** @var bool */
- protected $slaveOnly = false;
+ protected $replicaOnly = false;
/** @var int */
protected $syncTimeout = 3;
* required to hold the largest shard index. Data will be
* distributed across all tables by key hash. This is for
* MySQL bugs 61735 and 61736.
- * - slaveOnly: Whether to only use slave DBs and avoid triggering
+ * - slaveOnly: Whether to only use replica DBs and avoid triggering
* garbage collection logic of expired items. This only
* makes sense if the primary DB is used and only if get()
* calls will be used. This is used by ReplicatedBagOStuff.
- * - syncTimeout: Max seconds to wait for slaves to catch up for WRITE_SYNC.
+ * - syncTimeout: Max seconds to wait for replica DBs to catch up for WRITE_SYNC.
*
* @param array $params
*/
if ( isset( $params['syncTimeout'] ) ) {
$this->syncTimeout = $params['syncTimeout'];
}
- $this->slaveOnly = !empty( $params['slaveOnly'] );
+ $this->replicaOnly = !empty( $params['slaveOnly'] );
}
protected function getSeparateMainLB() {
$db = DatabaseBase::factory( $type, $info );
$db->clearFlag( DBO_TRX );
} else {
- $index = $this->slaveOnly ? DB_SLAVE : DB_MASTER;
+ $index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
if ( $this->getSeparateMainLB() ) {
$db = $this->getSeparateMainLB()->getConnection( $index );
$db->clearFlag( DBO_TRX ); // auto-commit mode
}
protected function garbageCollect() {
- if ( !$this->purgePeriod || $this->slaveOnly ) {
+ if ( !$this->purgePeriod || $this->replicaOnly ) {
// Disabled
return;
}
?: MediaWikiServices::getInstance()->getDBLoadBalancer();
if ( $lb->getServerCount() <= 1 ) {
- return true; // no slaves
+ return true; // no replica DBs
}
- // Main LB is used; wait for any slaves to catch up
+ // Main LB is used; wait for any replica DBs to catch up
$masterPos = $lb->getMasterPos();
$loop = new WaitConditionLoop(
return false;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$oldestRevisionTimestamp = $dbr->selectField(
'revision',
'MIN( rev_timestamp )',
if ( !$rc ) {
// Don't cache: This can be hit if the page gets accessed very fast after
- // its creation / latest upload or in case we have high slave lag. In case
+ // its creation / latest upload or in case we have high replica DB lag. In case
// the revision is too old, we will already return above.
return false;
}
// This, as a side-effect, also makes sure that the following query isn't being run for
// pages with a larger history, unless the user has the 'bigdelete' right
// (and is about to delete this page).
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$revisions = $edits = (int)$dbr->selectField(
'revision',
'COUNT(rev_page)',
* @return ResultWrapper
*/
protected function queryImageLinks( $target, $limit ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return $dbr->select(
[ 'imagelinks', 'page' ],
*
* @param int $id Article ID to load
* @param string|int $from One of the following values:
- * - "fromdb" or WikiPage::READ_NORMAL to select from a slave database
+ * - "fromdb" or WikiPage::READ_NORMAL to select from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST to select from the master database
*
* @return WikiPage|null
}
$from = self::convertSelectType( $from );
- $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_REPLICA );
$row = $db->selectRow(
'page', self::selectFields(), [ 'page_id' => $id ], __METHOD__ );
if ( !$row ) {
* @since 1.20
* @param object $row Database row containing at least fields returned by selectFields().
* @param string|int $from Source of $data:
- * - "fromdb" or WikiPage::READ_NORMAL: from a slave DB
+ * - "fromdb" or WikiPage::READ_NORMAL: from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST: from the master DB
* - "forupdate" or WikiPage::READ_LOCKING: from the master DB using SELECT FOR UPDATE
* @return WikiPage
*
* @param object|string|int $from One of the following:
* - A DB query result object.
- * - "fromdb" or WikiPage::READ_NORMAL to get from a slave DB.
+ * - "fromdb" or WikiPage::READ_NORMAL to get from a replica DB.
* - "fromdbmaster" or WikiPage::READ_LATEST to get from the master DB.
* - "forupdate" or WikiPage::READ_LOCKING to get from the master DB
* using SELECT FOR UPDATE.
$data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
if ( !$data
- && $index == DB_SLAVE
+ && $index == DB_REPLICA
&& wfGetLB()->getServerCount() > 1
&& wfGetLB()->hasOrMadeRecentMasterChanges()
) {
$data = $this->pageDataFromTitle( wfGetDB( $index ), $this->mTitle, $opts );
}
} else {
- // No idea from where the caller got this data, assume slave database.
+ // No idea from where the caller got this data, assume replica DB.
$data = $from;
$from = self::READ_NORMAL;
}
* @since 1.20
* @param object|bool $data DB row containing fields returned by selectFields() or false
* @param string|int $from One of the following:
- * - "fromdb" or WikiPage::READ_NORMAL if the data comes from a slave DB
+ * - "fromdb" or WikiPage::READ_NORMAL if the data comes from a replica DB
* - "fromdbmaster" or WikiPage::READ_LATEST if the data comes from the master DB
* - "forupdate" or WikiPage::READ_LOCKING if the data comes from
* the master DB using SELECT FOR UPDATE
*/
public function getOldestRevision() {
- // Try using the slave database first, then try the master
+ // Try using the replica DB first, then try the master
$continue = 2;
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$revSelectFields = Revision::selectFields();
$row = null;
$flags = Revision::READ_LOCKING;
} elseif ( $this->mDataLoadedFrom == self::READ_LATEST ) {
// Bug T93976: if page_latest was loaded from the master, fetch the
- // revision from there as well, as it may not exist yet on a slave DB.
+ // revision from there as well, as it may not exist yet on a replica DB.
// Also, this keeps the queries in the same REPEATABLE-READ snapshot.
$flags = Revision::READ_LATEST;
} else {
// links.
$hasLinks = (bool)count( $editInfo->output->getLinks() );
} else {
- $hasLinks = (bool)wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
+ $hasLinks = (bool)wfGetDB( DB_REPLICA )->selectField( 'pagelinks', 1,
[ 'pl_from' => $this->getId() ], __METHOD__ );
}
}
}
// Query the redirect table
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'redirect',
[ 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ],
[ 'rd_from' => $this->getId() ],
public function getContributors() {
// @todo FIXME: This is expensive; cache this info somewhere.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr->implicitGroupby() ) {
$realNameField = 'user_real_name';
$baseRevId = null;
if ( $edittime && $sectionId !== 'new' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$rev = Revision::loadFromTimestamp( $dbr, $this->mTitle, $edittime );
// Try the master if this thread may have just added it.
// This could be abstracted into a Revision method, but we don't want
// We get here if vary-revision is set. This means that this page references
// itself (such as via self-transclusion). In this case, we need to make sure
// that any such self-references refer to the newly-saved revision, and not
- // to the previous one, which could otherwise happen due to slave lag.
+ // to the previous one, which could otherwise happen due to replica DB lag.
$oldCallback = $edit->popts->getCurrentRevisionCallback();
$edit->popts->setCurrentRevisionCallback(
function ( Title $title, $parser = false ) use ( $revision, &$oldCallback ) {
$protectDescription = '';
foreach ( array_filter( $limit ) as $action => $restrictions ) {
- # $action is one of $wgRestrictionTypes = array( 'create', 'edit', 'move', 'upload' ).
+ # $action is one of $wgRestrictionTypes = [ 'create', 'edit', 'move', 'upload' ].
# All possible message keys are listed here for easier grepping:
# * restriction-create
# * restriction-edit
# * restriction-move
# * restriction-upload
$actionText = wfMessage( 'restriction-' . $action )->inContentLanguage()->text();
- # $restrictions is one of $wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' ),
+ # $restrictions is one of $wgRestrictionLevels = [ '', 'autoconfirmed', 'sysop' ],
# with '' filtered out. All possible message keys are listed below:
# * protect-level-autoconfirmed
# * protect-level-sysop
if ( $title->getNamespace() == NS_CATEGORY ) {
// Load the Category object, which will schedule a job to create
- // the category table row if necessary. Checking a slave is ok
+ // the category table row if necessary. Checking a replica DB is ok
// here, in the worst case it'll run an unnecessary recount job on
// a category that probably doesn't have many members.
Category::newFromTitle( $title )->getID();
return TitleArray::newFromResult( new FakeResultWrapper( [] ) );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'categorylinks',
[ 'cl_to AS page_title, ' . NS_CATEGORY . ' AS page_namespace' ],
// Have to do that since DatabaseBase::fieldNamesWithAlias treats numeric indexes
return [];
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( [ 'categorylinks', 'page_props', 'page' ],
[ 'cl_to' ],
[ 'cl_from' => $id, 'pp_page=page_id', 'pp_propname' => 'hiddencat',
}
$this->mIsBackwards = ( $this->mRequest->getVal( 'dir' ) == 'prev' );
- # Let the subclass set the DB here; otherwise use a slave DB for the current wiki
- $this->mDb = $this->mDb ?: wfGetDB( DB_SLAVE );
+ # Let the subclass set the DB here; otherwise use a replica DB for the current wiki
+ $this->mDb = $this->mDb ?: wfGetDB( DB_REPLICA );
$index = $this->getIndexField(); // column to sort on
$extraSort = $this->getExtraSortFields(); // extra columns to sort on for query planning
$output = $this->parent->getOutput();
$linkRenderer = $this->parent->getLinkRenderer();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
# Sort by namespace
ksort( $this->internals );
if ( !$linkBatch->isEmpty() ) {
// construct query
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = array_merge(
LinkCache::getSelectFields(),
[ 'page_namespace', 'page_title' ]
* @since 1.24
* @param Title $title
* @param Parser|bool $parser
- * @return Revision
+ * @return Revision|bool False if missing
*/
- public static function statelessFetchRevision( $title, $parser = false ) {
- return Revision::newFromTitle( $title );
+ public static function statelessFetchRevision( Title $title, $parser = false ) {
+ $pageId = $title->getArticleID();
+ $revId = $title->getLatestRevID();
+
+ $rev = Revision::newKnownCurrent( wfGetDB( DB_REPLICA ), $pageId, $revId );
+ if ( $rev ) {
+ $rev->setTitle( $title );
+ }
+
+ return $rev;
}
/**
*/
public function fetchScaryTemplateMaybeFromCache( $url ) {
global $wgTranscludeCacheExpiry;
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
$obj = $dbr->selectRow( 'transcache', [ 'tc_time', 'tc_contents' ],
[ 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ] );
// Or else Database*::select() will explode, plus it's cheaper!
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$skin = $context->getSkin();
$lang = $context->getLanguage();
$good = $fileCache->isCacheGood( wfTimestamp( TS_MW, time() - $maxage ) );
if ( !$good ) {
try { // RL always hits the DB on file cache miss...
- wfGetDB( DB_SLAVE );
+ wfGetDB( DB_REPLICA );
} catch ( DBConnectionError $e ) { // ...check if we need to fallback to cache
$good = $fileCache->isCacheGood(); // cache existence check
}
// Try in-object cache first
if ( !isset( $this->fileDeps[$vary] ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$deps = $dbr->selectField( 'module_deps',
'md_deps',
[
/**
* Get the Database object used in getTitleInfo().
*
- * Defaults to the local slave DB. Subclasses may want to override this to return a foreign
+ * Defaults to the local replica DB. Subclasses may want to override this to return a foreign
* database object, or null if getTitleInfo() shouldn't access the database.
*
* NOTE: This ONLY works for getTitleInfo() and isKnownEmpty(), NOT FOR ANYTHING ELSE.
* @return IDatabase|null
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
}
public static function suggestTarget( $target, array $ids ) {
- $result = wfGetDB( DB_SLAVE )->select( 'logging',
+ $result = wfGetDB( DB_REPLICA )->select( 'logging',
'log_type',
[ 'log_id' => $ids ],
__METHOD__,
* @return bool|mixed
*/
public static function checkRevisionExistence( $title, $revid ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$exists = $dbr->selectField( 'revision', '1',
[ 'rev_id' => $revid ], __METHOD__ );
if ( $db ) {
$this->db = $db;
} else {
- $this->db = wfGetDB( DB_SLAVE );
+ $this->db = wfGetDB( DB_REPLICA );
}
}
} elseif ( $configType !== null ) {
$class = $configType;
} else {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$class = $dbr->getSearchEngine();
}
if ( is_null( self::$mMinSearchLength ) ) {
$sql = "SHOW GLOBAL VARIABLES LIKE 'ft\\_min\\_word\\_len'";
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->query( $sql, __METHOD__ );
$row = $result->fetchObject();
$result->free();
protected function loadSites() {
$this->sites = new SiteList();
- $dbr = $this->dbLoadBalancer->getConnection( DB_SLAVE );
+ $dbr = $this->dbLoadBalancer->getConnection( DB_REPLICA );
$res = $dbr->select(
'sites',
$s = '';
}
- if ( wfGetLB()->getLaggedSlaveMode() ) {
+ if ( wfGetLB()->getLaggedReplicaMode() ) {
$s .= ' <strong>' . $this->msg( 'laggedslavemode' )->parse() . '</strong>';
}
$out = $this->getOutput();
$this->initPage( $out );
- $tpl = $this->prepareQuickTemplate( $out );
+ $tpl = $this->prepareQuickTemplate();
// execute template
$res = $tpl->execute();
* @return IDatabase
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE );
+ return wfGetDB( DB_REPLICA );
}
/**
* @return IDatabase
*/
function getRecacheDB() {
- return wfGetDB( DB_SLAVE, [ $this->getName(), 'QueryPage::recache', 'vslow' ] );
+ return wfGetDB( DB_REPLICA, [ $this->getName(), 'QueryPage::recache', 'vslow' ] );
}
/**
* @since 1.18
*/
public function fetchFromCache( $limit, $offset = false ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$options = [];
if ( $limit !== false ) {
$options['LIMIT'] = intval( $limit );
public function getCachedTimestamp() {
if ( is_null( $this->cachedTimestamp ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fname = get_class( $this ) . '::getCachedTimestamp';
$this->cachedTimestamp = $dbr->selectField( 'querycache_info', 'qci_timestamp',
[ 'qci_type' => $this->getName() ], $fname );
// Mention the level of cache staleness...
$cacheText = '';
- $dbr = wfGetDB( DB_SLAVE, 'recentchanges' );
+ $dbr = wfGetDB( DB_REPLICA, 'recentchanges' );
$rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
if ( $rcMax ) {
$cTime = $dbr->selectField( 'querycache_info',
list( $namespace, $fromKey, $from ) = $fromList;
list( , $toKey, $to ) = $toList;
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$filterConds = [ 'page_namespace' => $namespace ];
if ( $hideredirects ) {
$filterConds['page_is_redirect'] = 0;
case Block::TYPE_IP:
case Block::TYPE_RANGE:
list( $start, $end ) = IP::parseRange( $target );
- $conds[] = wfGetDB( DB_SLAVE )->makeList(
+ $conds[] = wfGetDB( DB_REPLICA )->makeList(
[
'ipb_address' => $target,
Block::getRangeCond( $start, $end )
} else {
$linkRenderer = $this->getLinkRenderer();
- $dbr = BotPassword::getDB( DB_SLAVE );
+ $dbr = BotPassword::getDB( DB_REPLICA );
$res = $dbr->select(
'bot_passwords',
[ 'bp_app_id' ],
}
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return [
'tables' => [
if ( !$pager->getNumRows() ) {
$out->addWikiMsg( 'nocontribs', $target );
} else {
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $pager->getDatabase() );
if ( $lag > 0 ) {
$out->showLagWarning( $lag );
return;
}
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $pager->getDatabase() );
if ( $lag > 0 ) {
$out->showLagWarning( $lag );
function reallyGetQueryInfo( $namespace = null, $title = null ) {
$limitToTitle = !( $namespace === null && $title === null );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$retval = [
'tables' => [
'ra' => 'redirect',
// get a little more detail about each individual entry quickly
// using the filter of reallyGetQueryInfo.
if ( $result && !isset( $result->nsb ) ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$qi = $this->reallyGetQueryInfo(
$result->namespace,
$result->title
/* Ok, let's get to it... */
if ( $history == WikiExporter::CURRENT ) {
$lb = false;
- $db = wfGetDB( DB_SLAVE );
+ $db = wfGetDB( DB_REPLICA );
$buffer = WikiExporter::BUFFER;
} else {
// Use an unbuffered query; histories may be very long!
$lb = wfGetLBFactory()->newMainLB();
- $db = $lb->getConnection( DB_SLAVE );
+ $db = $lb->getConnection( DB_REPLICA );
$buffer = WikiExporter::STREAM;
// This might take a while... :D
$name = $title->getDBkey();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'categorylinks' ],
[ 'page_namespace', 'page_title' ],
$maxPages = $this->getConfig()->get( 'ExportPagelistLimit' );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'page',
[ 'page_namespace', 'page_title' ],
* @return array
*/
private function getLinks( $inputPages, $pageSet, $table, $fields, $join ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
foreach ( $inputPages as $page ) {
$title = Title::newFromText( $page );
*/
static function mungeQuery( $query, $prot ) {
$field = 'el_index';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $query === '*' && $prot !== '' ) {
// Allow queries like 'ftp://*' to find all ftp links
}
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// strip everything past first wildcard, so that
// index-based-only lookup would be done
list( $this->mungedQuery, $clause ) = self::mungeQuery( $this->mQuery, $this->mProt );
* Special:BrokenRedirects also rely on this.
*/
public function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fakeTitle = $dbr->buildConcat( [
'img_media_type',
$dbr->addQuotes( ';' ),
( $oldTalk->exists()
|| ( $oldTitleTalkSubpages && $canMoveSubpage ) );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $this->getConfig()->get( 'FixDoubleRedirects' ) ) {
$hasRedirects = $dbr->selectField( 'redirect', '1',
[
$opts['OFFSET'] = $offset;
}
- $res = wfGetDB( DB_SLAVE )->select(
+ $res = wfGetDB( DB_REPLICA )->select(
'page_props',
'pp_propname',
'',
# ## @todo FIXME: Should complain if $fromNs != $namespace
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [
'page_namespace' => $namespace,
'join_conds' => [
'log_search' => [
'LEFT JOIN', [
- 'ls_field' => 'pr_id', 'ls_value = pr_id'
+ 'ls_field' => 'pr_id', 'ls_value = ' . $this->mDb->buildStringCast( 'pr_id' )
]
],
'logging' => [
]
];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$minClTime = $this->getTimestampOffset( $rand );
if ( $minClTime ) {
$qi['conds'][] = 'cl_timestamp ' . $op . ' ' .
* @throws MWException If category has no entries.
*/
protected function getMinAndMaxForCat( Title $category ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->selectRow(
'categorylinks',
[
* @return array Info for the title selected.
*/
private function selectRandomPageFromDB( $rand, $offset, $up, $fname = __METHOD__ ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query = $this->getQueryInfo( $rand, $offset, $up );
$res = $dbr->select(
}
private function selectRandomPageFromDB( $randstr, $fname = __METHOD__ ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query = $this->getQueryInfo( $randstr );
$res = $dbr->select(
public function __construct() {
parent::__construct( 'Randomrootpage' );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->extra[] = 'page_title NOT ' . $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() );
}
}
protected function getDB() {
- return wfGetDB( DB_SLAVE, 'recentchanges' );
+ return wfGetDB( DB_REPLICA, 'recentchanges' );
}
public function outputFeedLinks() {
* expects only one result set so we use UNION instead.
*/
- $dbr = wfGetDB( DB_SLAVE, 'recentchangeslinked' );
+ $dbr = wfGetDB( DB_REPLICA, 'recentchangeslinked' );
$id = $title->getArticleID();
$ns = $title->getNamespace();
$dbkey = $title->getDBkey();
'log_user_text',
];
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Gets the nested SQL statement which
// returns timestamp of the log with the given log ID
// continuing with this, as the user is just going to end up getting sent
// somewhere else. Additionally, if we keep going here, we end up
// populating the memcache of tag data (see ChangeTags::listDefinedTags)
- // with out-of-date data from the slave, because the slave hasn't caught
+ // with out-of-date data from the replica DB, because the replica DB hasn't caught
// up to the fact that a new tag has been created as part of an implicit,
// as yet uncommitted transaction on master.
if ( $out->getRedirect() !== '' ) {
* @return ResultWrapper
*/
public static function listAllPages() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return self::listPages( $dbr, '' );
}
* @return ResultWrapper
*/
public static function listPagesByPrefix( $prefix ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$title = Title::newFromText( $prefix );
if ( $title ) {
* @return ResultWrapper
*/
function listRevisions() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$tables = [ 'archive' ];
return null;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
return $dbr->select(
'filearchive',
ArchivedFile::selectFields(),
* @return Revision|null
*/
function getRevision( $timestamp ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$fields = [
'ar_rev_id',
* @return Revision|null Null when there is no previous revision
*/
function getPreviousRevision( $timestamp ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Check the previous deleted revision...
$row = $dbr->selectRow( 'archive',
}
// New-style: keyed to the text storage backend.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$text = $dbr->selectRow( 'text',
[ 'old_text', 'old_flags' ],
[ 'old_id' => $row->ar_text_id ],
* @return string|null
*/
function getLastRevisionText() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$row = $dbr->selectRow( 'archive',
[ 'ar_text', 'ar_flags', 'ar_text_id' ],
[ 'ar_namespace' => $this->title->getNamespace(),
* @return bool
*/
function isDeleted() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
[ 'ar_namespace' => $this->title->getNamespace(),
'ar_title' => $this->title->getDBkey() ],
$minor = $rev->isMinor() ? ChangesList::flag( 'minor' ) : '';
- $tags = wfGetDB( DB_SLAVE )->selectField(
+ $tags = wfGetDB( DB_REPLICA )->selectField(
'tag_summary',
'ts_tags',
[ 'ts_rev_id' => $rev->getId() ],
}
if ( $warning == 'exists' ) {
$msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
+ } elseif ( $warning == 'no-change' ) {
+ $file = $args;
+ $filename = $file->getTitle()->getPrefixedText();
+ $msg = "\t<li>" . wfMessage( 'fileexists-no-change', $filename )->parse() . "</li>\n";
+ } elseif ( $warning == 'duplicate-version' ) {
+ $file = $args[0];
+ $count = count( $args );
+ $filename = $file->getTitle()->getPrefixedText();
+ $message = wfMessage( 'fileexists-duplicate-version' )
+ ->params( $filename )
+ ->numParams( $count );
+ $msg = "\t<li>" . $message->parse() . "</li>\n";
} elseif ( $warning == 'was-deleted' ) {
# If the file existed before and was deleted, warn the user of this
$ltitle = SpecialPage::getTitleFor( 'Log' );
* Scale a file (probably with a locally installed imagemagick, or similar)
* and output it to STDOUT.
* @param File $file
- * @param array $params Scaling parameters ( e.g. array( width => '50' ) );
+ * @param array $params Scaling parameters ( e.g. [ width => '50' ] );
* @param int $flags Scaling flags ( see File:: constants )
* @throws MWException|UploadStashFileNotFoundException
* @return bool Success
* client to cache it forever.
*
* @param File $file
- * @param array $params Scaling parameters ( e.g. array( width => '50' ) );
+ * @param array $params Scaling parameters ( e.g. [ width => '50' ] );
* @param int $flags Scaling flags ( see File:: constants )
* @throws MWException
* @return bool Success
* @return string
*/
public static function softwareInformation() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Put the software in an array of form 'name' => 'version'. All messages should
// be loaded here, so feel free to use wfMessage in the 'name'. Raw HTML or
* @return IDatabase
*/
protected function getDB() {
- return wfGetDB( DB_SLAVE, 'watchlist' );
+ return wfGetDB( DB_REPLICA, 'watchlist' );
}
/**
$user = $this->getUser();
$output = $this->getOutput();
- # Show a message about slave lag, if applicable
+ # Show a message about replica DB lag, if applicable
$lag = wfGetLB()->safeGetLag( $dbr );
if ( $lag > 0 ) {
$output->showLagWarning( $lag );
*/
function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) {
$out = $this->getOutput();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$hidelinks = $this->opts->getValue( 'hidelinks' );
$hideredirs = $this->opts->getValue( 'hideredirs' );
'join_conds' => [ 'langlinks' => [ 'LEFT JOIN', 'll_from = page_id' ] ]
];
if ( $this->prefix ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$query['conds'][] = 'page_title ' . $dbr->buildLike( $this->prefix, $dbr->anyString() );
}
/**
* Determine which of the MediaWiki and MediaWiki_talk namespace pages exist.
- * Returns array( 'pages' => ..., 'talks' => ... ), where the subarrays have
+ * Returns [ 'pages' => ..., 'talks' => ... ], where the subarrays have
* an entry for each existing page, with the key being the message name and
* value arbitrary.
*
public static function getCustomisedStatuses( $messageNames, $langcode = 'en', $foreign = false ) {
// FIXME: This function should be moved to Language:: or something.
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select( 'page',
[ 'page_namespace', 'page_title' ],
[ 'page_namespace' => [ NS_MEDIAWIKI, NS_MEDIAWIKI_TALK ] ],
$month = isset( $options['month'] ) ? $options['month'] : false;
$this->getDateCond( $year, $month );
- // Most of this code will use the 'contributions' group DB, which can map to slaves
+ // Most of this code will use the 'contributions' group DB, which can map to replica DBs
// with extra user based indexes or partioning by user. The additional metadata
- // queries should use a regular slave since the lookup pattern is not all by user.
- $this->mDbSecondary = wfGetDB( DB_SLAVE ); // any random slave
- $this->mDb = wfGetDB( DB_SLAVE, 'contributions' );
+ // queries should use a regular replica DB since the lookup pattern is not all by user.
+ $this->mDbSecondary = wfGetDB( DB_SLAVE ); // any random replica DB
+ $this->mDb = wfGetDB( DB_REPLICA, 'contributions' );
}
function getDefaultQuery() {
}
$this->target = $target;
$this->namespace = $namespace;
- $this->mDb = wfGetDB( DB_SLAVE, 'contributions' );
+ $this->mDb = wfGetDB( DB_REPLICA, 'contributions' );
}
function getDefaultQuery() {
$nt = Title::newFromText( $this->mSearch );
if ( $nt ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mQueryConds[] = 'LOWER(img_name)' .
$dbr->buildLike( $dbr->anyString(),
strtolower( $nt->getDBkey() ), $dbr->anyString() );
if ( $this->mSearch !== '' ) {
$nt = Title::newFromText( $this->mSearch );
if ( $nt ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds[] = 'LOWER(' . $prefix . '_name)' .
$dbr->buildLike( $dbr->anyString(),
strtolower( $nt->getDBkey() ), $dbr->anyString() );
}
unset( $field );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr->implicitGroupby() ) {
$options = [ 'GROUP BY' => 'img_name' ];
} else {
$this->title = $source;
$this->articleID = $source->getArticleID();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$maxtimestamp = $dbr->selectField(
'revision',
'MIN(rev_timestamp)',
$likeVal = $opts->getValue( 'like' );
if ( !$this->getConfig()->get( 'MiserMode' ) && $likeVal !== '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$likeObj = Title::newFromText( $likeVal );
if ( $likeObj instanceof Title ) {
$like = $dbr->buildLike(
* @return array
*/
function getQueryInfo() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$conds = [];
// Don't show hidden names
}
// Lookup groups for all the users
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$groupRes = $dbr->select(
'user_groups',
[ 'ug_user', 'ug_group' ],
$warnings['empty-file'] = true;
}
+ $hash = $this->getTempFileSha1Base36();
$exists = self::getExistsWarning( $localFile );
if ( $exists !== false ) {
$warnings['exists'] = $exists;
+
+ // check if file is an exact duplicate of current file version
+ if ( $hash === $localFile->getSha1() ) {
+ $warnings['no-change'] = $localFile;
+ }
+
+ // check if file is an exact duplicate of older versions of this file
+ $history = $localFile->getHistory();
+ foreach ( $history as $oldFile ) {
+ if ( $hash === $oldFile->getSha1() ) {
+ $warnings['duplicate-version'][] = $oldFile;
+ }
+ }
}
if ( $localFile->wasDeleted() && !$localFile->exists() ) {
}
// Check dupes against existing files
- $hash = $this->getTempFileSha1Base36();
$dupes = RepoGroup::singleton()->findBySha1( $hash );
$title = $this->getTitle();
// Remove all matches against self
* Helper function: do the actual database query to fetch file metadata.
*
* @param string $key
- * @param int $readFromDB Constant (default: DB_SLAVE)
+ * @param int $readFromDB Constant (default: DB_REPLICA)
* @return bool
*/
- protected function fetchFileMetadata( $key, $readFromDB = DB_SLAVE ) {
+ protected function fetchFileMetadata( $key, $readFromDB = DB_REPLICA ) {
// populate $fileMetadata[$key]
$dbr = null;
if ( $readFromDB === DB_MASTER ) {
/**
* Get a database connection for the bot passwords database
- * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_SLAVE.
+ * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_REPLICA.
* @return DatabaseBase
*/
public static function getDB( $db ) {
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
: [];
}
$audience = $this->checkAudience( $audience );
- $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+ $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
: [];
* @throws MWException On unexpected database errors
*/
protected function getUsersByEmail( $email ) {
- $res = wfGetDB( DB_SLAVE )->select(
+ $res = wfGetDB( DB_REPLICA )->select(
'user',
User::selectFields(),
[ 'user_email' => $email ],
$this->getCacheKey( $cache ),
$cache::TTL_HOUR,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $cache ) {
- $setOpts += Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
+ $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
wfDebug( "User: cache miss for user {$this->mId}\n" );
$this->loadFromDatabase( self::READ_NORMAL );
public static function newFromConfirmationCode( $code, $flags = 0 ) {
$db = ( $flags & self::READ_LATEST ) == self::READ_LATEST
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$id = $db->selectField(
'user',
$conds[] = 'ug_user > ' . (int)$after;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$ids = $dbr->selectFieldValues(
'user_groups',
'ug_user',
if ( is_null( $this->mGroups ) ) {
$db = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $db->select( 'user_groups',
[ 'ug_group' ],
[ 'ug_user' => $this->mId ],
/**
* Get blocking information
- * @param bool $bFromSlave Whether to check the slave database first.
- * To improve performance, non-critical checks are done against slaves.
+ * @param bool $bFromSlave Whether to check the replica DB first.
+ * To improve performance, non-critical checks are done against replica DBs.
* Check when actually saving should be done against master.
*/
private function getBlockedStatus( $bFromSlave = true ) {
/**
* Check if user is blocked
*
- * @param bool $bFromSlave Whether to check the slave database instead of
+ * @param bool $bFromSlave Whether to check the replica DB instead of
* the master. Hacked from false due to horrible probs on site.
* @return bool True if blocked, false otherwise
*/
/**
* Get the block affecting the user, or null if the user is not blocked
*
- * @param bool $bFromSlave Whether to check the slave database instead of the master
+ * @param bool $bFromSlave Whether to check the replica DB instead of the master
* @return Block|null
*/
public function getBlock( $bFromSlave = true ) {
* Check if user is blocked from editing a particular article
*
* @param Title $title Title to check
- * @param bool $bFromSlave Whether to check the slave database instead of the master
+ * @param bool $bFromSlave Whether to check the replica DB instead of the master
* @return bool
*/
public function isBlockedFrom( $title, $bFromSlave = false ) {
return [];
}
$utp = $this->getTalkPage();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Get the "last viewed rev" timestamp from the oldest message notification
$timestamp = $dbr->selectField( 'user_newtalk',
'MIN(user_last_timestamp)',
* @return bool True if the user has new messages
*/
protected function checkNewtalk( $field, $id ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$ok = $dbr->selectField( 'user_newtalk', $field, [ $field => $id ], __METHOD__ );
if ( is_null( $this->mFormerGroups ) ) {
$db = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $db->select( 'user_former_groups',
[ 'ufg_group' ],
[ 'ufg_user' => $this->mId ],
if ( $this->mEditCount === null ) {
/* Populate the count, if it has not been populated yet */
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// check if the user_editcount field has been initialized
$count = $dbr->selectField(
'user', 'user_editcount',
// Only update the timestamp if the page is being watched.
// The query to find out if it is watched is cached both in memcached and per-invocation,
- // and when it does have to be executed, it can be on a slave
+ // and when it does have to be executed, it can be on a replica DB
// If this is the user's newtalk page, we always update the timestamp
$force = '';
if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) {
// Get a new user_touched that is higher than the old one.
// This will be used for a CAS check as a last-resort safety
- // check against race conditions and slave lag.
+ // check against race conditions and replica DB lag.
$newTouched = $this->newTouchedTimestamp();
$dbw = wfGetDB( DB_MASTER );
// Maybe the problem was a missed cache update; clear it to be safe
$this->clearSharedCache( 'refresh' );
// User was changed in the meantime or loaded with stale data
- $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave';
+ $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'replica';
throw new MWException(
"CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" .
" the version of the user to be saved is older than the current version."
$db = ( ( $flags & self::READ_LATEST ) == self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$options = ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING )
? [ 'LOCK IN SHARE MODE' ]
if ( $this->getId() == 0 ) {
return false; // anons
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$time = $dbr->selectField( 'revision', 'rev_timestamp',
[ 'rev_user' => $this->getId() ],
__METHOD__,
// Lazy initialization check...
if ( $dbw->affectedRows() == 0 ) {
// Now here's a goddamn hack...
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $dbr !== $dbw ) {
- // If we actually have a slave server, the count is
+ // If we actually have a replica DB server, the count is
// at least one behind because the current transaction
// has not been committed and replicated.
$this->mEditCount = $this->initEditCount( 1 );
} else {
- // But if DB_SLAVE is selecting the master, then the
+ // But if DB_REPLICA is selecting the master, then the
// count we just read includes the revision that was
// just added in the working transaction.
$this->mEditCount = $this->initEditCount();
} else {
if ( $this->mEditCount === null ) {
$this->getEditCount();
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->mEditCount += ( $dbr !== $dbw ) ? 1 : 0;
} else {
$this->mEditCount++;
* @return int Number of edits
*/
protected function initEditCount( $add = 0 ) {
- // Pull from a slave to be less cruel to servers
+ // Pull from a replica DB to be less cruel to servers
// Accuracy isn't the point anyway here
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$count = (int)$dbr->selectField(
'revision',
'COUNT(rev_user)',
// Load from database
$dbr = ( $this->queryFlagsUsed & self::READ_LATEST )
? wfGetDB( DB_MASTER )
- : wfGetDB( DB_SLAVE );
+ : wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user_properties',
* Get a new instance of this user that was loaded from the master via a locking read
*
* Use this instead of the main context User when updating that user. This avoids races
- * where that user was loaded from a slave or even the master but without proper locks.
+ * where that user was loaded from a replica DB or even the master but without proper locks.
*
* @return User|null Returns null if the user was not found in the DB
* @since 1.27
// Database::select() doesn't like empty arrays
return new ArrayIterator( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user',
User::selectFields(),
// Database::select() doesn't like empty arrays
return new ArrayIterator( [] );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
'user',
User::selectFields(),
public static function search( $audience, $search, $limit, $offset = 0 ) {
$user = User::newFromName( $search );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$prefix = $user ? $user->getName() : '';
$tables = [ 'user' ];
$cond = [ 'user_name ' . $dbr->buildLike( $prefix, $dbr->anyString() ) ];
* method of batch updating rows in a database. To use create a class
* implementing the RowUpdateGenerator interface and configure the
* BatchRowIterator and BatchRowWriter for access to the correct table.
- * The components will handle reading, writing, and waiting for slaves
+ * The components will handle reading, writing, and waiting for replica DBs
* while the generator implementation handles generating update arrays
* for singular rows.
*
* updated value within the database row.
*
* Sample Response:
- * return array(
+ * return [
* 'some_col' => 'new value',
* 'other_col' => 99,
- * );
+ * ];
*
* @param stdClass $row A row from the database
* @return array Map of column names to updated value within the
"tog-hideminor": "Hȳdan lytela adihtunga in nīwra andwendinga getæle",
"tog-hidepatrolled": "Hȳdan weardoda adihtunga in nīwra andwendinga getæle",
"tog-newpageshidepatrolled": "Hȳdan weardode trametas in nīwra andwendinga getæle",
+ "tog-hidecategorization": "Behȳd trameta floccas",
"tog-extendwatchlist": "Sprǣdan behealdungtæl tō īwenne ealla andwendinga, nā synderlīce þā nīwostan",
"tog-usenewrc": "Settan andwendunga on hēapas on trametum on nīwra andwendunga getæle and behealdungtæle",
"tog-numberheadings": "Settan rīm on forecwidas selflīce",
"tog-watchdefault": "Ēacnian mīn behealdungtæl mid trametum and ymelum þā ic adihte.",
"tog-watchmoves": "Ēacnian mīn behealdungtæl mid trametum and ymelum þā ic wege.",
"tog-watchdeletion": "Ēacnian mīn behealdungæl mid trametum and ymelum þā ic forlēose.",
+ "tog-watchuploads": "Eacne nīwa ymelan to mīnum weardgetæle",
"tog-minordefault": "Mearcian ealla adihtunga lytela tō gewunan",
"tog-previewontop": "Īwan forebysene ofer adihtunge mearce",
"tog-previewonfirst": "Īwan forebysene on forman adihtunge",
"علاء",
"Hhaboh162002",
"بدارين",
- "باسم"
+ "باسم",
+ "Moud hosny"
]
},
"tog-underline": "سطر تحت الوصلات:",
"filerevert-submit": "استرجع",
"filerevert-success": "'''[[Media:$1|$1]]''' تم استرجاعها [$4 للنسخة بتاريخ $3، $2].",
"filerevert-badversion": "لا توجد نسخة محلية سابقة لهذا الملف بالتاريخ المعطى.",
+ "filerevert-identical": "الإصدار الحالي من الملف بالفعل مطابق للإصدار المحدد.",
"filedelete": "احذف $1",
"filedelete-legend": "احذف الملف",
"filedelete-intro": "أنت على وشك حذف الملف '''[[Media:$1|$1]]''' مع كل تاريخه.",
"file-thumbnail-no": "El ficheru entama con <strong>$1</strong>.\nPaez ser una imaxe de tamañu menguáu ''(miniatura)''.\nSi tienes esta imaxe a resolución completa xúbila; si non, por favor camuda'l nome del ficheru.",
"fileexists-forbidden": "Yá esiste un ficheru con esti nome, y nun se pue renomar.\nSi tovía asina quies xubir el ficheru, por favor vuelvi atrás y usa otru nome.\n[[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Yá esiste un ficheru con esti nome nel direutoriu de ficheros compartíos.\nSi tovía asina quies xubir el ficheru, por favor vuelvi atrás y usa otru nome.\n[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "La carga ye un duplicáu exautu de la versión actual de <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Esti ficheru ye un duplicáu {{PLURAL:$1|del siguiente ficheru|de los siguientes ficheros}}:",
"file-deleted-duplicate": "Yá se desanició enantes un ficheru idénticu a esti ([[:$1]]).\nDeberíes revisar el historial de desaniciu del ficheru enantes de xubilu otra vuelta.",
"file-deleted-duplicate-notitle": "Un ficheru idénticu a esti desanicióse anteriormente, y suprimióse'l títulu. Tendría de pidir a dalguién que pueda ver los datos del ficheru desaniciáu que revise la situación enantes de volver a xubilu.",
"rollbacklinkcount-morethan": "revertir más de $1 {{PLURAL:$1|edición|ediciones}}",
"rollbackfailed": "Falló la reversión",
"rollback-missingparam": "Faltan parámetros riquíos na solicitú.",
+ "rollback-missingrevision": "Nun pueden cargase los datos de la revisión.",
"cantrollback": "Nun se pue revertir la edición; el postrer collaborador ye l'únicu autor d'esta páxina.",
"alreadyrolled": "Nun se pue revertir la postrer edición de [[:$1]] fecha por [[User:$2|$2]] ([[User talk:$2|alderique]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\ndaquién más yá editó o revirtió la páxina.\n\nLa postrer edición foi fecha por [[User:$3|$3]] ([[User talk:$3|alderique]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "El resume de la edición yera: <em>$1</em>.",
"linkaccounts-submit": "Enllazar cuentes",
"unlinkaccounts": "Desenllazar cuentes",
"unlinkaccounts-success": "Desenllazóse la cuenta.",
- "authenticationdatachange-ignored": "Nun se xestionó'l cambéu de los datos d'autentificacion. ¿Seique, nun se configuró un fornidor?"
+ "authenticationdatachange-ignored": "Nun se xestionó'l cambéu de los datos d'autentificacion. ¿Seique, nun se configuró un fornidor?",
+ "userjsispublic": "Atención: les subpáxines JavaScript nun tendríen de contener datos acutaos porque son visibles pa otros usuarios.",
+ "usercssispublic": "Atención: les subpáxines CSS nun tendríen de contener datos acutaos porque son visibles pa otros usuarios."
}
"filerevert-submit": "Вярнуць",
"filerevert-success": "'''[[Media:$1|$1]]''' быў вернуты да [вэрсіі $4 ад $3, $2].",
"filerevert-badversion": "Не існуе папярэдняй лякальнай вэрсіі гэтага файла з пазначанай датай.",
+ "filerevert-identical": "Цяперашняя вэрсія файлу ўжо ідэнтычная абранай.",
"filedelete": "Выдаліць $1",
"filedelete-legend": "Выдаліць файл",
"filedelete-intro": "Вы выдаляеце файл '''[[Media:$1|$1]]''' з усёй яго гісторыяй.",
"mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
"mw-widgets-titleinput-description-new-page": "старонка яшчэ не існуе",
"mw-widgets-titleinput-description-redirect": "перанакіраваньне на $1",
+ "sessionmanager-tie": "Немагчыма выкарыстаць адначасова некалькі тыпаў аўтэнтыфікацыі: $1.",
"sessionprovider-generic": "$1 сэсіі",
"randomrootpage": "Выпадковая карэнная старонка",
"log-action-filter-block": "Тып блякаваньня:",
"missingarticle-rev": "(সংস্করণ#: $1)",
"missingarticle-diff": "(পার্থক্য: $1, $2)",
"readonly_lag": "ডাটাবেজ স্বয়ংক্রিয়ভাবে বন্ধ করে দেয়া হয়েছে, যাতে অধীন ডাটাবেজ সার্ভারগুলি প্রধান ডাটাবেজ সার্ভারের অবস্থায় আসতে পারে।",
+ "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP শিরলেখে পাঠানো হয়েছিল কিন্তু অনুরোধটি একটি API লিখন মডিউলে ছিল।",
"internalerror": "আভ্যন্তরীণ ত্রুটি",
"internalerror_info": "আভ্যন্তরীণ ত্রুটি: $1",
"internalerror-fatal-exception": "\"$1\" ধরনের মারাত্মক ব্যতিক্রম",
"createacct-email-ph": "আপনার ইমেইল ঠিকানা যোগ করুন",
"createacct-another-email-ph": "আপনার ইমেইল ঠিকানা প্রবেশ করান",
"createaccountmail": "একটি র্যান্ডম পাসওয়ার্ড নির্বাচন করুন এবং নির্ধারিত ইমেইল ঠিকানায় পাঠিয়ে দিন",
+ "createaccountmail-help": "পাসওয়ার্ড জানা ছাড়াই অন্য ব্যক্তির জন্য অ্যাকাউন্ট তৈরি করতে ব্যবহার করা যেতে পারে।",
"createacct-realname": "আসল নাম (ঐচ্ছিক)",
"createaccountreason": "কারণ:",
"createacct-reason": "কারণ",
"nocookiesnew": "ব্যবহারকারীর অ্যাকাউন্টটি সৃষ্টি করা হয়েছে, কিন্তু আপনি এখনও অ্যাকাউন্টে প্রবেশ করেননি। {{SITENAME}}-তে কুকি ব্যবহার করে ব্যবহারকারীদের অ্যাকাউন্টে প্রবেশ করানো হয়। আপনার ব্রাউজারে কুকিগুলি নিষ্ক্রিয় করা আছে। অনুগ্রহ করে কুকিগুলি সক্রিয় করুন এবং আপনার নতুন ব্যবহারকারী নাম ও পাসওয়ার্ড ব্যবহার করে অ্যাকাউন্টে প্রবেশ করুন।",
"nocookieslogin": "ব্যবহারকারীদের প্রবেশ সম্পন্ন করতে {{SITENAME}} কুকি ব্যবহার করে। আপনার ব্রাউজারে কুকি নিষ্ক্রিয় করা আছে। কুকি চালু করে আবার চেষ্টা করুন।",
"nocookiesfornew": "ব্যবহারকারীর অ্যাকাউন্ট তৈরি হয়নি, কারণ এর উৎস সম্পর্কে আমরা নিশ্চিত নই।\nনিশ্চিত করুন আপনার কুকি সক্রিয় রয়েছে, পাতাটি পুনরায় লোড করে আবার চেষ্টা করুন।",
+ "createacct-loginerror": "অ্যাকাউন্ট সফলভাবে তৈরি করা হয়েছে কিন্তু আপনি স্বয়ংক্রিয়ভাবে প্রবেশ করতে পারবেন না। দয়া করে [[Special:UserLogin|ম্যানুয়াল প্রবেশ]] করতে এগিয়ে যান।",
"noname": "আপনি সঠিক ব্যবহারকারী নাম নির্দিষ্ট করেননি।",
"loginsuccesstitle": "প্রবেশ করেছেন",
"loginsuccess": "<strong>আপনি এইমাত্র \"$1\" নামে {{SITENAME}}-তে প্রবেশ করেছেন।</strong>",
"uploadscripted": "এই ফাইলে এমন HTML বা স্ক্রিপ্ট কোড আছে যা একটি ওয়েব ব্রাউজার ভুল বুঝতে পারে।",
"uploaded-script-svg": "আপলোডকৃত SVG ফাইলে স্ক্রিপ্টযোগ্য উপাদান \"$1\" পাওয়া গেছে।",
"uploaded-hostile-svg": "আপলোড করা SVG ফাইলের শৈলী উপাদানে অনিরাপদ সিএসএস পাওয়া গেছে।",
+ "uploaded-href-unsafe-target-svg": "অনিরাপদ উপাত্তে href পাওয়া গেছে: আপলোডকৃত SVG ফাইলে URI লক্ষ্য ছিল <code><$1 $2=\"$3\"></code>।",
"uploaded-image-filter-svg": "আপলোডকৃত SVG ফাইলে URL: <code><$1 $2=\"$3\"></code> সহ ছবি পরিশোধক পাওয়া গেছে।",
"uploadscriptednamespace": "এই SVG ফাইলে অবৈধ নামস্থান \"$1\" রয়েছে",
"uploadinvalidxml": "আপলোডকৃত ফাইলে XML পার্স করা যাবে না।",
"upload-form-label-own-work": "এটি আমার নিজের কাজ",
"upload-form-label-infoform-categories": "বিষয়শ্রেণীসমূহ",
"upload-form-label-infoform-date": "তারিখ",
+ "upload-form-label-own-work-message-generic-local": "আমি নিশ্চিত করছি যে আমি {{SITENAME}}-এর পরিষেবা এবং লাইসেন্সকরণ নীতির শর্তাবলী অনুসরণ করে এই ফাইল আপলোড করছি।",
"upload-form-label-not-own-work-local-generic-local": "এছাড়াও আপনি [[Special:Upload|ডিফল্ট আপলোডের পাতা]] চেষ্টা করতে পারেন।",
"upload-form-label-not-own-work-local-generic-foreign": "এছাড়াও আপনি [[Special:Upload|{{SITENAME}}-এর আপলোডের পাতা]] ব্যবহার করার চেষ্টা করতে পারেন, যদি এই ফাইলটি তাদের নীতিমালা অধীনে সেখানে আপলোড করা যায়।",
"backend-fail-stream": "\"$1\" ফাইলের স্ট্রিম দেখানো যাচ্ছে না।",
"backend-fail-read": "$1 ফাইলটি ওপেন করা যাচ্ছে না।",
"backend-fail-create": "$1 ফাইলটি তৈরী করা যাচ্ছে না।",
"backend-fail-maxsize": "\"$1\" ফাইলে লেখা যাচ্ছে না কারণ এটি {{PLURAL:$2|এক বাইট|$2 বাইট}} থেকে বড়।",
- "backend-fail-readonly": "\"$1\" সà§\8dà¦\9fà§\8bরà§\87à¦\9c বà§\8dযাà¦\95à¦\8fনà§\8dড থà§\87à¦\95à§\87 বরà§\8dতমানà§\87 লà§\87à¦\96া যাà¦\9aà§\8dà¦\9bà§\87 না। à¦\95ারণ: \"''$2''\"",
+ "backend-fail-readonly": "\"$1\" সà§\8dà¦\9fà§\8bরà§\87à¦\9c বà§\8dযাà¦\95à¦\8fনà§\8dড থà§\87à¦\95à§\87 বরà§\8dতমানà§\87 শà§\81ধà§\81-পঠনà§\87 রয়à§\87à¦\9bà§\87। পà§\8dরদতà§\8dত à¦\95ারণ: <em>$2</em>",
"backend-fail-synced": "\"$1\" ফাইলটি ইন্টারনাল স্টোরেজ ব্যকএন্ডের সাথে অসামঞ্জস্যপূর্ণ",
"backend-fail-connect": "স্টোরেজ ব্যাকেন্ড \"$1\" এর সাথে যোগাযোগ করা যাচ্ছে না।",
"backend-fail-internal": "\"$1\" স্টোরেজ ব্যাকেন্ডে কোনো অজানা ত্রুটি হয়েছে।",
"uploadstash-errclear": "ফাইলগুলো পরিষ্কারকরণ ব্যর্থ হয়েছে।",
"uploadstash-refresh": "ফাইলের তালিকা রিফ্রেশ করুন",
"uploadstash-thumbnail": "থাম্বনেইল দেখুন",
+ "uploadstash-exception": "স্টাসে আপলোড সঞ্চয় করা যায়নি ($1): \"$2\"।",
"invalid-chunk-offset": "ত্রুটিপূর্ণ চাংক অফসেট",
"img-auth-accessdenied": "প্রবেশাধিকার নাই",
"img-auth-nopathinfo": "PATH_INFO পাওয়া যাচ্ছে না।\nআপনার সার্ভার থেকে এই তথ্য পাঠানোর জন্য কনফিগার করা হয়নি।\nএটি হয়তো CGI ভিত্তিক এবং img_auth সমর্থন করে না।\nবিস্তারিত দেখুন https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization।",
"apisandbox-fullscreen": "প্যানেল সম্প্রসারণ করুন",
"apisandbox-fullscreen-tooltip": "ব্রাউজারের উইন্ডো পূরণ করতে খেলাঘরের প্যানেল প্রসারিত করুন।",
"apisandbox-unfullscreen": "পাতা দেখাও",
+ "apisandbox-unfullscreen-tooltip": "খেলাঘরের প্যানেল হ্রাস করুন, তাহলে মিডিয়াউইকি পরিভ্রমণ করার সংযোগগুলি পাওয়া যাবে।",
"apisandbox-submit": "অনুরোধ রাখুন",
"apisandbox-reset": "পরিস্কার",
"apisandbox-retry": "পুনঃচেষ্টা করুন",
"listgrouprights-removegroup-self-all": "নিজের অ্যাকাউন্ট থেকে সকল দল অপসারণ",
"listgrouprights-namespaceprotection-header": "নামস্থান নিষেধাজ্ঞাসমূহ",
"listgrouprights-namespaceprotection-namespace": "নামস্থান",
+ "listgrants": "কার্যভার",
+ "listgrants-summary": "নিম্নে ব্যবহারকারী অধিকারের সাথে যুক্ত প্রবেশাধিকারসহ তাদের কার্যভারের একটি তালিকা দেয়া হয়েছে। ব্যবহারকারীরা তাদের অ্যাকাউন্ট ব্যবহার করতে অ্যাপ্লিকেশনকে অনুমোদন দিতে পারে, কিন্তু কার্যভারের উপর ভিত্তি করে সীমিত অনুমতি ব্যবহারকারীরা অ্যাপ্লিকেশনকে দিতে পারবেন। মূলত, একটি অ্যাপ্লিকেশন একজন ব্যবহারকারীর দেয়া অধিকারের অতিরিক্ত অধিকার ব্যবহার করতে পারবে না। পৃথক অধিকার সম্পর্কে [[{{MediaWiki:Listgrouprights-helppage}}|অতিরিক্ত তথ্য]] দেখুন।",
+ "listgrants-grant": "কার্যভার",
"listgrants-rights": "অধিকারসমূহ",
"trackingcategories": "বিষয়শ্রেণীসমূহ অনুসরণ করা হচ্ছে",
"trackingcategories-msg": "বিষয়শ্রেণী অনুসরণ করা হচ্ছে",
"restricted-displaytitle-ignored": "উপেক্ষিত প্রদর্শন শিরোনামসহ পাতা",
"restricted-displaytitle-ignored-desc": "পাতাটি একটি <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> উপেক্ষা করেছে কারণ এটা পাতাটির আসল শিরোনামের সাথে সমতুল্য নয়।",
"broken-file-category-desc": "এই পাতায় একটি ভাঙ্গা ফাইলের লিঙ্ক রয়েছে (একটি ফাইল এম্বেড করার জন্য একটি লিঙ্ক যখন ফাইলটির অস্তিত্ব নেই)",
+ "hidden-category-category-desc": "এই বিষয়শ্রেণীটির পাতার বিষয়বস্তুর মধ্যে <code><nowiki>__HIDDENCAT__</nowiki></code> উপস্থিত রয়েছে, যা পূর্ব-নির্ধারিতভাবে পাতার বিষয়শ্রেণীর সংযোগে দেখায় না।",
"trackingcategories-nodesc": "কোন বর্ণনা নেই।",
"trackingcategories-disabled": "বিষয়শ্রেণীটি বিকল",
"mailnologin": "প্রাপকের ঠিকানা নেই",
"rollbacklinkcount": "$1টি {{PLURAL:$1|সম্পাদনা}} রোলব্যাক করুন",
"rollbacklinkcount-morethan": "$1টির বেশি {{PLURAL:$1|সম্পাদনা}} রোলব্যাক করুন",
"rollbackfailed": "রোলব্যাক ব্যর্থ",
+ "rollback-missingparam": "অনুরোধে প্রয়োজনীয় প্যারামিটারগুলি অনুপস্থিত।",
+ "rollback-missingrevision": "সংশোধনের উপাত্ত লোড করতে অক্ষম।",
"cantrollback": "পূর্বের সংস্করণে ফেরত যাওয়া সম্ভব হল না, সর্বশেষ সম্পাদনাকারী এই নিবন্ধটির একমাত্র লেখক।",
"alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) দ্বারা সম্পাদিত সর্বশেষ [[:$1]] সম্পাদনাটি পুনর্বহাল করা যাচ্ছে না;\nঅন্য কোন ব্যবহারকারী এই পাতা ইতিমধ্যে সম্পাদনা বা পুনর্বহাল করেছেন।\n\nএই পাতায় সর্বোশেষে [[User:$3|$3]] ([[User talk:$3|talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) দ্বারা সম্পাদিত।",
"editcomment": "সম্পাদনা সারাংশ ছিল: \"''$1''\"।",
"undeletedrevisions": "{{PLURAL:$1|১টি সংশোধন|$1টি সংশোধন}} পুনরুদ্ধার করা হয়েছে",
"undeletedrevisions-files": "{{PLURAL:$1|১টি সংশোধন|$1টি সংশোধন}} এবং {{PLURAL:$2|১টি ফাইল|$2টি ফাইল}} পুনরুদ্ধার করা হয়েছে",
"undeletedfiles": "{{PLURAL:$1|১টি ফাইল|$1টি ফাইল}} পুনরুদ্ধার করা হয়েছে",
- "cannotundelete": "মà§\81à¦\9bà§\87 ফà§\87লা বাতিল করা যায়নি:\n$1",
+ "cannotundelete": "à¦\95িà¦\9bà§\81 বা সব পà§\81নরà§\81দà§\8dধার করা যায়নি:\n$1",
"undeletedpage": "'''$1 পুনরুদ্ধার করা হয়েছে'''\n\nসাম্প্রতিক মুছে ফেলা ও পুনরুদ্ধারের ঘটনাগুলির জন্য [[Special:Log/delete|অবলুপ্তি লগ]] দেখুন।",
"undelete-header": "সাম্প্রতিক সময়ে মুছে ফেলা পাতাগুলি দেখতে [[Special:Log/delete|অবলুপ্তি লগ]] দেখুন।",
"undelete-search-title": "অপসারিত পাতা অনুসন্ধান করো",
"sp-contributions-newbies-sub": "নতুন অ্যাকাউন্টের জন্য",
"sp-contributions-newbies-title": "নতুন অ্যাকাউন্টের ব্যবহারকারী অবদান",
"sp-contributions-blocklog": "বাধা দানের লগ",
- "sp-contributions-suppresslog": "মà§\81à¦\9bà§\87 ফà§\87লা বà§\8dযবহারà¦\95ারà§\80 অবদান",
- "sp-contributions-deleted": "মুছে ফেলা ব্যবহারকারী অবদান",
+ "sp-contributions-suppresslog": "à¦\97à§\8bপনà¦\95à§\83ত {{GENDER:$1|বà§\8dযবহারà¦\95ারà§\80র}} অবদান",
+ "sp-contributions-deleted": "মুছে ফেলা {{GENDER:$1|ব্যবহারকারীর}} অবদান",
"sp-contributions-uploads": "আপলোডসমূহ",
"sp-contributions-logs": "লগসমূহ",
"sp-contributions-talk": "আলোচনা",
"move-page-legend": "পাতা স্থানান্তর",
"movepagetext": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\nযেসমস্ত পুনর্নির্দেশনা পুরনো শিরোনামটির দিকে নির্দেশ করছিল, সেগুলি স্বয়ংক্রিয়ভাবে হালনাগাদ করতে পারবেন।\nযদি তা না চান, তবে [[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে।\nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে; অগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
"movepagetext-noredirectfixer": "নিচের ফর্মটি ব্যবহার করে একটি পাতার শিরোনাম পরিবর্তন করা যাবে, এবং সেই সাথে নতুন শিরোনামে এর সমগ্র ইতিহাস স্থানান্তর করা যাবে।\nপুরনো শিরোনামটি নতুন শিরোনামটির প্রতি একটি পুনর্নির্দেশনা ধারণ করবে।\n[[Special:DoubleRedirects|দ্বি-পুনর্নির্দেশনা]] বা [[Special:BrokenRedirects|অচল পুনর্নির্দেশনাগুলি]] পরীক্ষা করে দেখতে ভুলবেন না।\nসংযোগগুলি যাতে তাদের লক্ষ্যে পৌঁছায়, তা নিশ্চিত করার দায়িত্ব আপনার।\n\nলক্ষ্য করুন যে যদি নতুন শিরোনামে ইতিমধ্যেই একটি পাতা থেকে থাকে, তবে উৎস পাতাটি সেই শিরোনামে স্থানান্তর করা হবে <strong>না</strong>, যদি না নতুন শিরোনামের পাতাটি খালি থাকে বা একটি পুননির্দেশনা হয় এবং এর কোন অতীত সম্পাদনা ইতিহাস না থাকে। \nঅর্থাৎ আপনি ভুল করে নাম পরিবর্তন করলে সহজেই পুরনো নামে ফেরত যেতে পারবেন, কিন্তু ইতিমধ্যে বিদ্যমান কোন পাতার উপরে লিখতে পারবেন না।\n\n<strong>টীকা:</strong>\nকোন জনপ্রিয় পাতার ক্ষেত্রে এই পরিবর্তনটি খুবই আকস্মিক হতে পারে;\nঅগ্রসর হবার আগে এই কাজটির ফলাফল কী হতে পারে, সে ব্যাপারে অনুগ্রহ করে নিশ্চিত হোন।",
- "movepagetalktext": "পাতাà¦\9fির সাথà§\87 সাথà§\87 সà¦\82শà§\8dলিষà§\8dà¦\9f à¦\86লà§\8bà¦\9aনা পাতাà¦\9fিà¦\93 সà§\8dবয়à¦\82à¦\95à§\8dরিয়à¦à¦¾à¦¬à§\87 সরানà§\8b হবà§\87 '''যদি না:'''\n*à¦\96ালি নয় à¦\8fমন à¦\8fà¦\95à¦\9fি à¦\86লাপ পাতা নতà§\81ন শিরà§\8bনামà¦\9fির à¦\85ধà§\80নà§\87 à¦\87তিমধà§\8dযà§\87à¦\87 বিদà§\8dযমান থাà¦\95à§\87, à¦\85থবা\n*à¦\86পনি নিà¦\9aà§\87র বাà¦\95à§\8dসà¦\9fি থà§\87à¦\95à§\87 à¦\9fিà¦\95 সরিয়à§\87 নিতà§\87 পারà§\87ন।\n\nএসব ক্ষেত্রে আপনি চাইলে নিজের হাতে পাতাটিকে সরাতে বা একত্রীকরণ করতে পারেন।",
+ "movepagetalktext": "à¦\86পনি যদি à¦\8fà¦\87 বাà¦\95à§\8dসà§\87 à¦\9fিà¦\95 দà§\87ন, তাহলà§\87 পাতাà¦\9fির সাথà§\87 সà¦\82শà§\8dলিষà§\8dà¦\9f à¦\86লà§\8bà¦\9aনা পাতাà¦\9fিà¦\93 সà§\8dবয়à¦\82à¦\95à§\8dরিয়à¦à¦¾à¦¬à§\87 নতà§\81ন শিরà§\8bনামà§\87 সরানà§\8b হবà§\87 যদি না নতà§\81ন শিরà§\8bনামà¦\9fির à¦\85ধà§\80নà§\87 à¦\87তিমধà§\8dযà§\87à¦\87 à¦\8fà¦\95à¦\9fি বিদà§\8dযমান থাà¦\95à§\87।\n\nএসব ক্ষেত্রে আপনি চাইলে নিজের হাতে পাতাটিকে সরাতে বা একত্রীকরণ করতে পারেন।",
"moveuserpage-warning": "'''সতর্কতা:''' আপনি একটি ব্যবহারকারী পাতা স্থানান্তর করছেন। অনুগ্রহ করে লক্ষ্য করুন যে এর মাধ্যমে কেবলমাত্র পাতাটি স্থানান্তর হবে, কিন্তু পাতার নাম পরিবর্তন হবে ''না''।",
"movecategorypage-warning": "<strong>সতর্কীকরণ:</strong> আপনি একটি বিষয়শ্রেণীর পাতা স্থানান্তর করতে চলেছেন। দয়া করে মনে রাখবেন যে এতে শুধুমাত্র পাতাটি স্থানান্তরিত হবে এবং পুরাতন বিষয়শ্রেণীতে থাকা কোন পাতা নতুনটিতে পুনঃশ্রেণীকরণ করা হবে <em>না</em>।",
"movenologintext": "কোন পাতা সরিয়ে ফেলতে চাইলে আপনাকে অবশ্যই একজন নিবন্ধিত ব্যবহারকারী হতে হবে ও অ্যাকাউন্টে [[Special:UserLogin|প্রবেশ]] করতে হবে।",
"mediastatistics-header-office": "অফিস",
"mediastatistics-header-archive": "সংকুচিত বিন্যাস",
"mediastatistics-header-total": "সকল ফাইল",
+ "json-warn-trailing-comma": "JSON থেকে $1টি সর্বশেষ {{PLURAL:$1|কমা}} সরানো হয়েছে",
"json-error-unknown": "JSON-এ একটি সমস্যা রয়েছে। ত্রুটি: $1",
+ "json-error-depth": "সর্বাধিক স্ট্যাকের গভীরতা অতিক্রম হয়েছে",
"json-error-state-mismatch": "অকার্যকর বা ত্রুটিপূর্ণ JSON",
"json-error-ctrl-char": "অক্ষর নিয়ন্ত্রণ ত্রুটি, সম্ভবত ভুল এনকোডকৃত",
"json-error-syntax": "সিনট্যাক্স ত্রুটি",
"log-action-filter-block": "বাধাদানের ধরন:",
"log-action-filter-delete": "অপসারণের ধরন:",
"log-action-filter-import": "আমদানির ধরন:",
+ "log-action-filter-managetags": "ট্যাগ ব্যবস্থাপনা কার্যের ধরন:",
+ "log-action-filter-move": "স্থানান্তরের ধরন:",
+ "log-action-filter-newusers": "অ্যাকাউন্ট তৈরির ধরন:",
"log-action-filter-patrol": "টহলের ধরন:",
"log-action-filter-protect": "সুরক্ষার ধরন:",
+ "log-action-filter-rights": "অধিকার পরিবর্তনের ধরন:",
"log-action-filter-upload": "আপলোডের ধরন:",
"log-action-filter-all": "সব",
"log-action-filter-block-block": "বাধাদান",
"log-action-filter-delete-revision": "সংশোধন অপসারণ",
"log-action-filter-import-interwiki": "আন্তঃউইকি আমদানি",
"log-action-filter-import-upload": "XML আপলোড কর্তৃক আমদানি",
+ "log-action-filter-managetags-create": "ট্যাগ সৃষ্টিকরণ",
+ "log-action-filter-managetags-delete": "ট্যাগ অপসারণ",
+ "log-action-filter-managetags-activate": "ট্যাগ সক্রিয়করণ",
+ "log-action-filter-managetags-deactivate": "ট্যাগ নিষ্ক্রিয়করণ",
"log-action-filter-newusers-create": "বেনামী ব্যবহারকারী দ্বারা সৃষ্টি",
"log-action-filter-newusers-create2": "নিবন্ধিত ব্যবহারকারী দ্বারা সৃষ্টি",
"log-action-filter-newusers-autocreate": "স্বয়ংক্রিয় সৃষ্টি",
"log-action-filter-upload-upload": "নতুন আপলোড",
"log-action-filter-upload-overwrite": "পুনঃআপলোড",
"authmanager-authn-no-primary": "সরবরাহকৃত পরিচয়পত্রের অনুমোদন যাচাই করা যায়নি।",
+ "authmanager-create-disabled": "অ্যাকাউন্ট সৃষ্টিকরণ নিষ্ক্রিয় করা হয়েছে।",
"authmanager-create-from-login": "আপনার একাউন্ট তৈরি করতে, নীচের ক্ষেত্রগুলি পূরণ করুন।",
"authmanager-authplugin-setpass-failed-title": "পাসওয়ার্ড পরিবর্তন ব্যর্থ হয়েছে",
"authmanager-authplugin-setpass-bad-domain": "অবৈধ ডোমেইন।",
"authprovider-confirmlink-success-line": "$1: সংযোগ করা সফল হয়েছে।",
"authprovider-resetpass-skip-label": "উপেক্ষা করো",
"authprovider-resetpass-skip-help": "পাসওয়ার্ড পুনঃস্থাপন করা উপেক্ষা করুন।",
+ "authform-newtoken": "টোকেন অনুপস্থিত। $1",
+ "authform-notoken": "টোকেন অনুপস্থিত",
"authform-wrongtoken": "ভুল টোকেন",
"specialpage-securitylevel-not-allowed-title": "অনুমতি নেই",
+ "specialpage-securitylevel-not-allowed": "দুঃখিত, আপনি এই পাতা ব্যবহার করতে অনুমতিপ্রাপ্ত নন কারণ আপনার পরিচয় যাচাই করা যায়নি।",
"cannotauth-not-allowed-title": "অনুমতি অস্বীকৃত",
"cannotauth-not-allowed": "আপনি এই পাতাটি ব্যবহার করতে অনুমতিপ্রাপ্ত নন।",
"changecredentials": "পরিচয়পত্র পরিবর্তন করুন",
"credentialsform-provider": "পরিচয়পত্রের ধরন:",
"credentialsform-account": "অ্যাকাউন্টের নাম:",
"linkaccounts": "অ্যাকাউন্ট সংযোগ করুন",
+ "linkaccounts-submit": "অ্যাকাউন্ট সংযোগ করুন",
+ "unlinkaccounts": "অ্যাকাউন্ট সংযোগ বিচ্ছিন্ন করুন",
+ "unlinkaccounts-success": "অ্যাকাউন্টের সংযোগ বিচ্ছিন্ন করা হয়েছে।",
"userjsispublic": "অনুগ্রহ করে লক্ষ্য করুন: জাভাস্ক্রিপ্টের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।",
"usercssispublic": "অনুগ্রহ করে লক্ষ্য করুন: সিএসএসের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।"
}
"content-model-json": "JSON",
"content-json-empty-object": "Objecte buit",
"content-json-empty-array": "Matriu buida",
+ "deprecated-self-close-category": "Pàgines que usen etiquetes HTML autotancades no vàlides",
"duplicate-args-warning": "<strong>Avís:</strong> [[:$1]] crida [[:$2]] amb més d'un valor pel paràmetre «$3». Només s'utilitzarà el darrer valor proporcionat.",
"duplicate-args-category": "Pàgines amb arguments duplicats en utilització de plantilles",
"duplicate-args-category-desc": "La pàgina conté crides a plantilles que fan servir duplicats d'arguments, com ara <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
"minoredit": "Жима хийцам",
"watchthis": "ХӀара агӀо тергаме могӀанан юкъатоха",
"savearticle": "АгӀо дӀаязъян",
+ "savechanges": "Ӏалашбе хийцамаш",
+ "publishpage": "АгӀо кхолла",
"preview": "Хьалххе хьажар",
"showpreview": "Хьалха хьажар",
"showdiff": "Бина болу хийцамашка хьажар",
"searchprofile-articles-tooltip": "$1 чохь лахар",
"searchprofile-images-tooltip": "Файлаш лахар",
"searchprofile-everything-tooltip": "Массо агӀонашкахь лахар (дийцаре агӀонашца)",
- "searchprofile-advanced-tooltip": "Ð\94еÑ\85аÑ\80Ñ\86а йолÑ\83 Ñ\86Ó\80еÑ\80ийн анашкахь лахар",
+ "searchprofile-advanced-tooltip": "Ð\94еÑ\85аÑ\80Ñ\86а йолÑ\83 Ñ\86Ó\80еÑ\80ийн меÑ\82Ñ\82игашкахь лахар",
"search-result-size": "$1 ({{PLURAL:$2|$2 дош|$2 дешнаш}})",
"search-result-category-size": "$1 {{PLURAL:$1|юкъаяр}} ($2 {{PLURAL:$2|1=бухара категори|бухара категореш}}, $3 {{PLURAL:$3|1=файл|файлаш}}).",
"search-redirect": "(дӀасахьажийна $1)",
"search-showingresults": "{{PLURAL:$4|Карийна <strong>$1</strong> — цхьаъ агӀо|И дош карийна <strong>$3</strong> агӀонашкахь, царех гойту $2 агӀо}}",
"search-nonefound": "Дехаре терра цхьа хӀума ца карийна.",
"powersearch-legend": "Шуьйра лахар",
- "powersearch-ns": "ЦÓ\80еÑ\80ийн анашкахь лахар:",
+ "powersearch-ns": "ЦÓ\80еÑ\80ийн меÑ\82Ñ\82игашкахь лахар:",
"powersearch-togglelabel": "Билгалдан:",
"powersearch-toggleall": "Массо",
"powersearch-togglenone": "ХӀумма цаоьшу",
"tooltip-ca-nstab-category": "Категорешан агӀо",
"tooltip-minoredit": "Къастам бé хӀокху хийцамна кӀеззиг болуш санна",
"tooltip-save": "Хьан хийцамаш Ӏалашбой",
+ "tooltip-publish": "Гучубаха хьой бина хийцамаш",
"tooltip-preview": "Дехар до, агӀо Ӏалаш ярал хьалха хьажа муха ю из!",
"tooltip-diff": "Гайта долуш долу йозанах бина болу хийцам.",
"tooltip-compareselectedversions": "ХӀокху агӀона шина хаьржина версийн башхалле хьажар.",
"minoredit": "ئەمە دەستکارییەکی بچووکە",
"watchthis": "ئەم پەڕەیە بخە ژێر چاودێری",
"savearticle": "پەڕەکە پاشەکەوت بکە",
+ "savechanges": "پاشەکەوتکردنی گۆڕانکارییەکان",
"preview": "پێشبینین",
"showpreview": "پێشبینین نیشان بدە",
"showdiff": "گۆڕانکارییەکان نیشان بدە",
"filerevert-submit": "Vrátit zpět",
"filerevert-success": "Soubor '''[[Media:$1|$1]]''' byl vrácen zpět na [$4 verzi z $3 $2].",
"filerevert-badversion": "Není dostupná předchozí verze tohoto souboru s odpovídající časovou značkou.",
+ "filerevert-identical": "Aktuální verze souboru se již od vybrané verze neliší.",
"filedelete": "Smazání souboru $1",
"filedelete-legend": "Smazat soubor",
"filedelete-intro": "Chystáte se smazat soubor '''[[Media:$1|$1]]''' i s celou historií.",
"minoredit": "Dette er en mindre ændring",
"watchthis": "Overvåg denne side",
"savearticle": "Gem side",
+ "savechanges": "Gem ændringer",
"publishpage": "Offentliggør side",
"publishchanges": "Offentliggør ændringer",
"preview": "Forhåndsvisning",
"rightslogtext": "Dette er en log over ændringer i brugeres rettigheder.",
"action-read": "se denne side",
"action-edit": "redigere denne side",
- "action-createpage": "oprette sider",
- "action-createtalk": "oprette diskussionssider",
+ "action-createpage": "oprette denne side",
+ "action-createtalk": "oprette denne diskussionsside",
"action-createaccount": "Oprette denne brugerkonto",
"action-history": "se historik for denne side",
"action-minoredit": "markere denne redigering som mindre",
"upload-form-label-infoform-title": "Detaljer",
"upload-form-label-infoform-name": "Navn",
"upload-form-label-infoform-description": "Beskrivelse",
+ "upload-form-label-usage-title": "Anvendelse",
"upload-form-label-usage-filename": "Filnavn",
"upload-form-label-infoform-categories": "Kategorier",
"upload-form-label-infoform-date": "Dato",
"log-title-wildcard": "Søg i titler som begynder med teksten",
"showhideselectedlogentries": "Vis/skjul de markerede loghændelser",
"log-edit-tags": "Rediger tags i valgte logposter",
+ "checkbox-all": "Alle",
+ "checkbox-none": "Ingen",
"allpages": "Alle sider",
"nextpage": "Næste side ($1)",
"prevpage": "Forrige side ($1)",
"listgrouprights-namespaceprotection-header": "Navnerumsbegrænsninger",
"listgrouprights-namespaceprotection-namespace": "Navnerum",
"listgrouprights-namespaceprotection-restrictedto": "Rettighed(er) der giver brugeren mulighed for at redigere",
+ "listgrants-rights": "Rettigheder",
"trackingcategories": "Sporingskategorier",
"trackingcategories-summary": "Denne side viser sporing af de kategorier, som er automatisk udfyldt af MediaWiki-softwaren. Deres navne kan ændres ved at ændre de relevante system-beskeder i {{ns:8}}-navnerummet.",
"trackingcategories-msg": "Sporingskategori",
"nextn-title": "{{PLURAL:$1|Folgendes Ergebnis|Folgende $1 Ergebnisse}}",
"shown-title": "Zeige $1 {{PLURAL:$1|Ergebnis|Ergebnisse}} pro Seite",
"viewprevnext": "Zeige ($1 {{int:pipe-separator}} $2) ($3)",
- "searchmenu-exists": "<strong>Es gibt eine Seite, die den Namen „[[:$1]]“ hat.</strong> {{PLURAL:$2|0=|Weitere Suchergebnisse anzeigen.}}",
+ "searchmenu-exists": "<strong>Es gibt eine Seite, die den Namen „[[:$1]]“ hat.</strong> {{PLURAL:$2|0=|Weitere Suchergebnisse:}}",
"searchmenu-new": "<strong>Erstelle die Seite „[[:$1]]“ in diesem Wiki.</strong> {{PLURAL:$2|0=|Siehe auch die über deine Suche gefundene Seite.|Siehe auch die gefundenen Suchergebnisse.}}",
"searchprofile-articles": "Inhaltsseiten",
"searchprofile-images": "Multimedia",
"file-thumbnail-no": "Der Dateiname beginnt mit <strong>$1</strong>. Dies deutet auf ein Bild verringerter Größe ''(Minitatur)'' hin.\nBitte prüfe, ob du das Bild in voller Auflösung vorliegen hast und lade dieses unter dem Originalnamen hoch.",
"fileexists-forbidden": "Unter diesem Namen existiert bereits eine Datei und sie kann nicht überschrieben werden. Bitte gehe zurück und lade die Datei unter einem anderen Namen hoch. [[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "Unter diesem Namen existiert bereits eine Datei im zentralen Medienarchiv.\nWenn du diese Datei trotzdem hochladen möchtest, gehe bitte zurück und ändere den Namen.\n[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "Die hochgeladene Datei ist ein exaktes Duplikat der aktuellen Version von <strong>[[:$1]]</strong>.",
+ "fileexists-duplicate-version": "Die hochgeladene Datei ist ein exaktes Duplikat {{PLURAL:$2|einer älteren Version|von älteren Versionen}} von <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "Diese Datei ist ein Duplikat der folgenden {{PLURAL:$1|Datei|$1 Dateien}}:",
"file-deleted-duplicate": "Eine mit dieser identische Datei ([[:$1]]) wurde früher gelöscht. Sieh das Lösch-Logbuch ein, bevor du sie hochlädst.",
"file-deleted-duplicate-notitle": "Eine identische Datei wurde kürzlich gelöscht und der Titel wurde unterdrückt.\nDu solltest jemanden fragen, der die Möglichkeit hat, die unterdrückten Dateidaten anzusehen, um die Situation vor dem erneuten Hochladen zu überprüfen.",
"filerevert-submit": "Zurücksetzen",
"filerevert-success": "'''[[Media:$1|$1]]''' wurde auf die [$4 Version vom $2, $3 Uhr] zurückgesetzt.",
"filerevert-badversion": "Es gibt keine Version der Datei zu dem angegebenen Zeitpunkt.",
+ "filerevert-identical": "Die aktuelle Version der Datei ist bereits mit der ausgewählten Version identisch.",
"filedelete": "Lösche „$1“",
"filedelete-legend": "Lösche Datei",
"filedelete-intro": "Du löschst die Datei '''„[[Media:$1|$1]]“''' inklusive ihrer Versionsgeschichte.",
"hidden-categories": "{{PLURAL:$1|Kategoriya nımıtiye|Kategoriyê nımıtey}}",
"hidden-category-category": "Kategoriyê nımıtey",
"category-subcat-count": "{{PLURAL:$2|Na kategoriya de $1 bınkategoriyay estê.|$2 kategoriyan ra $1 bınkategoriyay asenê.}} \n(K) Kategori (D) Dosya (P) Pela",
- "category-subcat-count-limited": "Na kategoriya de {{PLURAL:$1|ena kategoriya bınên est a|enê $1 kategoriyay bınêni est ê}}.",
+ "category-subcat-count-limited": "Na kategoriye de {{PLURAL:$1|na kategoriya bınêne esta|nê $1 kategoriyê bınêni estê}}.",
"category-article-count": "{{PLURAL:$2|Na kategoriye de teyna ena pele esta.|Ebe $2 ra pêro piya {{PLURAL:$1|ena pela na kategoriye dera|$1 enê peli na kategoriye derê.}}}}",
"category-article-count-limited": "{{PLURAL:$1|Pela cêrêne|$1 Pelê cêrêni}} na kategoriye derê.",
- "category-file-count": "<noinclude>{{PLURAL:$2|Na kategoriya tenya dosyanê cêrênan muhtewa kena.}}</noinclude>\n*Na kategoriya de $2 dosyan ra {{PLURAL:$1|yew dosya tenêka esta| $1 dosyay asenê}}.",
+ "category-file-count": "{{PLURAL:$2|Na kategori tenya dosya ya cêri muhtewa kena.|Na kategori de $2 ra pêro piya {{PLURAL:$1|1 dosya est a|$1 dosyey est ê}}.}}",
"category-file-count-limited": "{{PLURAL:$1|Dosya cêrêne|$1 Dosyê cêrêni}} na kategoriye derê.",
"listingcontinuesabbrev": "dewam...",
"index-category": "Pelê endeksıni",
"morenotlisted": "Vêşi lista nêbi...",
"mypage": "Pele",
"mytalk": "Mesac",
- "anontalk": "Mesac",
+ "anontalk": "Werênayış",
"navigation": "Pusula",
"and": " u",
"qbfind": "Bıvêne",
"unprotectthispage": "Starkerdışe ena peler bıvurne",
"newpage": "Pela newiye",
"talkpage": "Ena pele sero werêne",
- "talkpagelinktext": "mesac",
+ "talkpagelinktext": "werênayış",
"specialpage": "Pela xısusiye",
"personaltools": "Hacetê şexsiy",
"articlepage": "Pera zerreki bıvin",
"mergehistory-box": "revizyonê pelanî yew bike:",
"mergehistory-from": "Pela çımey:",
"mergehistory-into": "Pela destinasyonî",
- "mergehistory-list": "tarixê vurnayîşî ke eşkeno yew bi.",
+ "mergehistory-list": "Tarixê vurnayışiyo yewbiyaye",
"mergehistory-merge": "[[:$1]] qey ney revizyonê cêrini [[:$2]] şıma ekeni piyawani. Benatê wexto muwaqqet de piyayanayişê rezizyonan de tuşa radyo bıxebitne.",
"mergehistory-go": "Yew bıyaye vurriyayışa bıasne",
"mergehistory-submit": "revizyonî yew bike",
"mergelog": "Qeydé zew kerdışi",
"revertmerge": "Abırnê",
"mergelogpagetext": "Cêr de yew liste esta ke mocnena ra, raya tewr peyêne kamci pela tarixi be a bine ra şanawa pê.",
- "history-title": "Tarixê çım ra viyarnayışë \"$1\"",
+ "history-title": "Tarixê çımraviyarnayışê \"$1\"",
"difference-title": "Pela \"$1\" ferqê çım ra viyarnayışan",
"difference-title-multipage": "Ferkê pelan dê \"$1\" u \"$2\"",
"difference-multipage": "(Ferqê pelan)",
"prefs-labs": "Xacetê labs",
"prefs-user-pages": "Pelê karberi",
"prefs-personal": "Pela karberi",
- "prefs-rc": "Vuriyayışë peyëni",
+ "prefs-rc": "Vurriyayışê peyêni",
"prefs-watchlist": "Lista seyrkerdışi",
"prefs-editwatchlist": "Lista seyrkerdışi bıvurne",
"prefs-editwatchlist-label": "Listey serkerdışanê cıkewtışi timar kerê",
"nchanges": "$1 {{PLURAL:$1|fın vurna|fıni vurna}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ra yok wazino}}",
"enhancedrc-history": "tarix",
- "recentchanges": "Vuriyayışë peyëni",
+ "recentchanges": "Vurriyayışê peyêni",
"recentchanges-legend": "Tercihê vurnayışanê peyênan",
"recentchanges-summary": "Wiki sero vurriyayışê peyêni asenê.",
"recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
"rcshowhidepatr-show": "Bımocne",
"rcshowhidepatr-hide": "Bınımne",
"rcshowhidemine": "vurnayışanê mı $1",
- "rcshowhidemine-show": "Bımocne",
+ "rcshowhidemine-show": "Bımosne",
"rcshowhidemine-hide": "Bınımne",
"rcshowhidecategorization": "kategorizasyonê pele $1",
"rcshowhidecategorization-show": "Bımocne",
"protectedpages-unknown-performer": "Karbero nêzanaye",
"protectedtitles": "Sernameyê pawıteyi",
"protectedtitlesempty": "pê ney parametreyan sernuşteyê pawite çinê",
- "protectedtitles-submit": "Sernaman bımocne",
+ "protectedtitles-submit": "Sernameyan bımocne",
"listusers": "Listeyê Karberan",
"listusers-editsonly": "Teyna karberan bimucne ke ey nuştê",
"listusers-creationsort": "goreyê wextê vıraştışi rêz ker",
"sp-contributions-deleted": "iştırakê karberi esterdi",
"sp-contributions-uploads": "Barkerdışi",
"sp-contributions-logs": "qeydi",
- "sp-contributions-talk": "mesac",
+ "sp-contributions-talk": "werênayış",
"sp-contributions-userrights": "idareyê heqanê karberan",
"sp-contributions-blocked-notice": "verniyê no/na karber/e geriyayo/a\nqê referansi qeydê vernigrewtışi cêr de eşkera biyo:",
"sp-contributions-blocked-notice-anon": "Eno adresê IPi bloke biyo.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
"cant-move-user-page": "desturê şıma çino, şıma pelanê karberani bıkırışi (bê pelê cerıni).",
"cant-move-to-user-page": "desturê şıma çino, şıma yew peli bıkırışi pelê yew karberi.",
"newtitle": "Sernameyo newe:",
- "move-watch": "Peler seyr ke",
+ "move-watch": "Na pele seyr ke",
"movepagebtn": "Pele bere",
"pagemovedsub": "Berdışi kerd temam",
"movepage-moved": "'''\"$1\" berd \"$2\"'''",
"tooltip-ca-nstab-main": "Pela zerreki bıvêne",
"tooltip-ca-nstab-user": "Pela karberi bıvêne",
"tooltip-ca-nstab-media": "Pela medya bıvêne",
- "tooltip-ca-nstab-special": "Na pelaya xas a, şıma nêşenê sero vurnayış bıkerê",
+ "tooltip-ca-nstab-special": "Na yew pela xasa, şıma nêşenê sero vurnayış bıkerê",
"tooltip-ca-nstab-project": "Pela proceyi bıvêne",
"tooltip-ca-nstab-image": "Pera dosyayer bıvin",
"tooltip-ca-nstab-mediawiki": "Mesacê sistemi bımocne",
"pageinfo-header-edits": "Veréna timar kerdışi",
"pageinfo-header-restrictions": "Sıtarkerdışê pele",
"pageinfo-header-properties": "Xısusiyetê pele",
- "pageinfo-display-title": "Sernuştey bımocne",
+ "pageinfo-display-title": "Sernuşteyo ke mosneyêno",
"pageinfo-default-sort": "Hesıbyaye mırfeyo kılm",
"pageinfo-length": "Derdeya pela (bayti heta)",
"pageinfo-article-id": "Kamiya pele",
"exif-pixelydimension": "Berzeya resimi",
"exif-usercomment": "Mışewreyê karberi",
"exif-relatedsoundfile": "Derhekê dosya yê vengi",
- "exif-datetimeoriginal": "Zeman u tarixê data varaziyayişi",
- "exif-datetimedigitized": "Zeman u tarixê dicital kerdişi",
+ "exif-datetimeoriginal": "Demê afernayışê dayeyo sıfteyıni",
+ "exif-datetimedigitized": "Zeman û tarixê dicitalkerdışi",
"exif-subsectime": "ZemanTarix saniyeyibini",
"exif-subsectimeoriginal": "ZemanTarixOricinal saniyeyibini",
"exif-subsectimedigitized": "ZemanTarixDicital saniyeyibini",
"version": "Versiyon",
"version-extensions": "Ekstensiyonî ke ronaye",
"version-skins": "Bar kerde bejni",
- "version-specialpages": "Pelanê xasiyan",
+ "version-specialpages": "Pelê xısusiyi",
"version-parserhooks": "Çengelê Parserî",
"version-variables": "Vurnayeyî",
"version-antispam": "Spam vındarnayış",
"specialpages-note-top": "Kıtabek",
"specialpages-note": "* Pelê xasê normali.\n* <span class=\"mw-specialpagerestricted\">Pelê xasê nımıtey.</span>",
"specialpages-group-maintenance": "Raporê pawıtışi",
- "specialpages-group-other": "Pelê xasiyê bini",
+ "specialpages-group-other": "Pelê xısusiyê bini",
"specialpages-group-login": "Dekew / hesab vıraz",
"specialpages-group-changes": "Vurnayışê peyêni û qeydi",
"specialpages-group-media": "Raporê medya û barkerdışi",
"tagline": "{{SITENAME}}बाट",
"help": "सहायता",
"search": "खोज",
+ "search-ignored-headings": " #<!-- leave this line exactly as it is --> <pre>\n# Headings that will be ignored by search.\n# Changes to this take effect as soon as the page with the heading is indexed.\n# You can force page reindexing by doing a null edit.\n# The syntax is as follows:\n# * Everything from a \"#\" character to the end of the line is a comment.\n# * Every non-blank line is the exact title to ignore, case and everything.\nReferences\nExternal links\nSee also\n #</pre> <!-- leave this line exactly as it is -->",
"searchbutton": "खोज",
"go": "जाने",
"searcharticle": "जाओ",
"import-logentry-upload-detail": "$1 {{PLURAL:$1|संशोधन|संशोधनहरू}} आयात भयो",
"tooltip-pt-userpage": "{{GENDER:|तमरो प्रयोगकर्ता}} पान्नो",
"tooltip-pt-anonuserpage": "तमी जो IP ठेगानाको रुपमी सम्पादन गद्दै छौ , त्यैको प्रयोगकर्ता पानो निम्न छ :",
- "tooltip-pt-mytalk": "{{GENDER:|तमरà¥\8b}} à¤\95à¥\81रडà¥\80à¤\95ानà¥\80 पानà¥\8dनà¥\8b",
+ "tooltip-pt-mytalk": "{{GENDER:|तमरो}} कुरडीकानी पानो",
"tooltip-pt-preferences": "{{GENDER:|तमरी}} अभिरुचि",
"tooltip-pt-watchlist": "पृष्ठहरूको सूची जैका फेरबदलहरुलाई तमले पहरा गरिराखेका छौ ।",
"tooltip-pt-mycontris": "{{GENDER:|तमरा}} योगदानअनऐ सूची",
"noemail": "Nisûn indirés ed pôsta eletrônica registrê per l'utèint $1.",
"noemailcreate": "L'é necesâri dêr un 'indirés ed pôsta eletrônica vâlid.",
"passwordsent": "'Na nōva cêva 'd ingrès l'é stêda spidîda a l'indiré ed pôsta eletrônica per l'utèint \"$1\". Per piaşèir, fà un ingrès apèina 't la ricēv.",
- "blocked-mailpassword": "Per pervèder abûş, an n'é mìa permès druvêr la funsiòun \"spidés 'na nōva cêva 'd ingrès\" da un indirés IP bluchê.",
+ "blocked-mailpassword": "Al tó indirés IP l’è bluchê int la mudéfica. Per pervèder abûş, an n'é mìa permès druvêr la funsiòun ed recóper ed la cêva ‘d ingrès da cl’indirés IP ché.",
"eauthentsent": "Un mesâg ed cunfèirma l'é stê spidî a l'indirés ed pôsta eletrônica sgnê ché. L'utèint per prèir inviêr di mesâg ed pôsta eletrônica al dēv andêr a drē al j istrusiòun scréti, in môd da cunfermêr ch' l'é ló al legétim proprietâri 'd l'indirés.",
"throttled-mailpassword": "Un mesâg ed pôsta eletrônica 'd arnōv ed la cêva 'd ingrès l'é bèle stê inviê da mēno 'd {{PLURAL:$1|1 ōra|$1 ōri}}. Per pervèder abûş, la funziòun 'd arnōv ed la cêva 'd ingrès la pōl èser druvêda sōl 'na vôlta ògni {{PLURAL:$1|1 ōra|$1 ōri}}.",
"mailerror": "Erōr int la spedisiòun dal mesâg $1",
"createaccount-title": "Per fêr un inscrisiòun a {{SITENAME}}",
"createaccount-text": "Quelchidûn l'à fât un inscrisiòun a {{SITENAME}} ($4) a nòm ed $2 coleghê a cl'indirés ed pôsta eletrônica ché. La cêva 'd ingrès per l'utèint \"$2\" l'é impustêda a \"$3\". \nÉ necesâri fêr un ingrès préma ch' es pôl e cambiêr subét la cêva 'd ingrès. \nSe l'inscrisiòun l'é stêda fâta per şbâli, es pōl scanşlêr sté mesâg.",
"login-throttled": "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr.",
- "login-abort-generic": "An t'é mìa stê arcgnusû - Scanşlê",
+ "login-abort-generic": "Al tó ingrès an n’è mia stê fât – Al vîn scanşlê",
"login-migrated-generic": "La tó utèinsa l'é stêda spustêda, e al tó nòm utèint al gh'é mìa pió in sém a cla wiki ché.",
"loginlanguagelabel": "Léngva: $1",
"suspicious-userlogout": "La tó dmânda per destachêret l'é stēda rifiutêda perchè la sèmbra spidîda da un navigadōr ch' al funsiòuna mìa o da un proxy di caching.",
"newpassword": "Nōva cêva 'd ingrès:",
"retypenew": "Scrév incòra la nōva cêva 'd ingrès:",
"resetpass_submit": "Scrév la cêva 'd ingrès e và dèinter al sît",
- "changepassword-success": "La cêva 'd ingrès l'é stêda nudifichêda!",
+ "changepassword-success": "La tó cêva 'd ingrès l'é stêda mudifichêda!",
"changepassword-throttled": "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr.",
"resetpass_forbidden": "An 'né mìa pusébil mudifichêr la cêva 'd ingrès",
"resetpass-no-info": "Per andêr dèinter a cla pàgina ché 't gh'ê da fêr l'ingrès.",
"resetpass-submit-loggedin": "Câmbia la cêva 'd ingrès",
"resetpass-submit-cancel": "Scanşèla",
- "resetpass-wrong-oldpass": "Cêva 'd ingrès pruvişôria o còla 'd adès mìa vâlida.\nLa cêva 'd ingrès la pré èser stêda bèle cambiêda, opór n'in pré èser stê dmandê 'na nōva pruvişôria.",
+ "resetpass-wrong-oldpass": "Cêva 'd ingrès pruvişôria o còla 'd adès an n'é mìa vâlida.\nLa cêva 'd ingrès la pré èser stêda bèle cambiêda, opór in pré èser stê dmandê 'na nōva pruvişôria.",
"resetpass-recycled": "Mèt dèinter 'na cêva 'd ingrès divêrsa da còla 'd adès.",
"resetpass-temp-emailed": "L'ingrès l'é stê fât cun un côdis pruvişôri. Per finîr la registrasiòun, l'é necesâri impustêr 'na nōva cêva 'd ingrès ché:",
"resetpass-temp-password": "Cêva 'd ingrès pruvişôria:",
"passwordreset-emailtext-ip": "Quelchidûn (prubabilmèint té, cun l'indirés IP $1) l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:\n \n$2 \n\n{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. \n\nSe t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia.",
"passwordreset-emailtext-user": "L'utèint $1 ed {{SITENAME}} l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:\n\n$2 \n\n{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria ché la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. \n\nSe t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia",
"passwordreset-emailelement": "Nòm utèint: \n$1\n.\nCêva 'd ingrès pruvişôria: \n$2",
- "passwordreset-emailsentemail": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès.",
- "changeemail": "Câmbia l'indirés ed la pôsta eletrônica",
- "changeemail-header": "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
+ "passwordreset-emailsentemail": "Se cl’indirés ed pôsta eletrônica ché l’è unî a la tó utèinsa, alōra a gnirà spidî ‘na lètra per per turnêr a impustêr la cêva ‘d ingrès.",
+ "changeemail": "Mudéfica o tó via l'indirés ed pôsta eletrônica",
+ "changeemail-header": "Finés cól fòj ché per cambiêr al tó indirés ed pôsta eletrônica, 'S an 't vō mia avèir nisûn indirés coleghê a la tó utèinsa lêsa vōd al spâsi per l'indirés nōv quând té spidés al fòj.",
"changeemail-no-info": "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
"changeemail-oldemail": "L'indirés ed la pôsta eletrànica 'd adès.",
"changeemail-newemail": "Nōv indirés ed pàsta eletrônica:",
"sig_tip": "Fîrma cun la dâta e l'ōra",
"hr_tip": "Rîga spiâna (drōva cun giudési)",
"summary": "Ogèt:",
- "subject": "Argumèint (tétol):",
+ "subject": "Argumèint:",
"minoredit": "Còsta l'é 'na mudéfica céca",
"watchthis": "Tîn adrē a cla pàgina ché",
"savearticle": "Sêlva la pàgina",
"missingsummary": "'''Atensiòun:''' an n'é mìa stê precişê al mutîv de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda cun al mutîv vōd.",
"selfredirect": "<strong>Ateinti:</strong>t'é drē fêr un rinvéi a l'istèsa pàgina. Ét prés avèir şbaliê sgnêr al pôst dal rinvéi o t'é drē mudifichêr la pàgina şbaliêda. S'ét fê cléch incòra in sém a \"{{int:savearticle}}\", al rinvéi al gnirà fât in tót' al manēri.",
"missingcommenttext": "Scréver un cumèint ché sòta.",
- "missingcommentheader": "'''Atensiòun:''' an n'é mìa stê precişê al mutîv/al tétol de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda sèinsa tétol.",
+ "missingcommentheader": "<strong>Atensiòun:<strong> an n'é mìa stê precişê l'argumèint de sté mudéfica. S'es tōrna a clichêr insém a \"{{int:savearticle}}\" la mudéfica la gnirà salvêda sèinsa.",
"summary-preview": "Guêrda préma sûnt:",
- "subject-preview": "Guêrda préma argumèint/tétol:",
+ "subject-preview": "Guêrda préma l'argumèint:",
"previewerrortext": "A gh'é stê 'n erōr mèinter a s'é serchê ed guardêr al lavōr préma 'd salvêrel.",
"blockedtitle": "Utèint bluchê",
"blockedtext": " '''Al tō nòm utèint o indirés IP l'é stê bluchê.'''\n\nAl blôch l'é stê fât da $1. Al mutîv dal blôch l'é còst: ''$2''.\n\n*Inési dal blôch: $8\n*Scadèinsa dal blôch: $6\n*Intervâl ed blôch: $7\n\nS' ét vō, l'é pusébil mètres in cuntât cun $1 o 'n êter [[{{MediaWiki:Grouppage-sysop}}|aministradōr]] per discóter dal blôch.\n\nGuêrda che la funsiòun 'Scrév a l'utèint' an n'é mìa in ôvra s' an n'é mìa stê registrtê un indirés ed pôsta eletrônica vâlid int al tō [[Special:Preferences| preferèinsi]] o se sté funsiòun l'é stêda bluchêda. L'indirés IP 'd adèsa l'é $3, al nóme ID dal blôch l'é #$5. T'é perghê ed precişêr tót j elemèint ed préma per ògni dmânda de spiegasiòun",
"accmailtext": "'Na cêva 'd ingrés l'è stêda fâta a chêş per [[User talk:$1|$1]] e l'è stêda spidîda a $2. Cla cêva 'd ingrès ché la pōl èser cambiêda int la pàgina per ''[[Special:ChangePassword|cambiêr la cêva 'd ingrès]]'' subét dôp avèir fât l'ingrès.",
"newarticle": "(Nōv)",
"newarticletext": "Al colegamèint apèina fât al cumbîna cun 'na pàgina ch' an n'é mìa incòra stêda fâta. S'ét vō fêr la pàgina adès, l'é asê cumincêr a scréver al tèst int la caşèla ché sòt (per vedèr infurmasiòun pió precîşi guêrda la [$1 pàgina 'd ajót]). Se al colegamèint l'é stê avêrt per erōr, l'é asê clichêr al pulsânt \"Indrē\" dal tó navigadōr.",
- "anontalkpagetext": "----'' Còsta l'è la pàgina 'd discusiòun ed 'n utèint sèinsa nòm, ch' an n' à mìa incòra fât 'n' utèinsa o in tót al manēri an n'è mìa drē druvêrla. Per arcgnòsrel l'è dòunca necesâri druvê al só indirés IP. J indirés IP a pōlen èser spartî cun êter utèint. Se t'è un utèint sèinsa nòm e 't pèins che i cumèint in cla pàgina ché an riguêrden mìa tè, [[Special:CreateAccount|fa 'n' utèinsa nōva]] o [[Special:UserLogin|vîn dèinter cun còla ch' ét gh'ê bèle]] per schivşêr, in futûr, 'd èser cunfûş cun 'd j êter utèint sèinsa nòm.''",
+ "anontalkpagetext": "----\n<em>Còsta l'è la pàgina 'd discusiòun ed 'n utèint sèinsa nòm, ch' an n' à mìa incòra fât 'n' utèinsa o in tót al manēri an n'è mìa drē druvêrla.</em> Per arcgnòsrel l'è dòunca necesâri druvê al nóme dal só indirés IP. J indirés IP a pōlen èser spartî cun êter utèint. Se t'é un utèint sèinsa nòm e 't pèins che i cumèint in cla pàgina ché an riguêrden mìa té, [[Special:CreateAccount|fa 'n' utèinsa nōva]] o [[Special:UserLogin|vîn dèinter cun còla ch' ét gh'ê bèle]] per schivşêr, in futûr, 'd èser cunfûş cun 'd j êter utèint sèinsa nòm.",
"noarticletext": "In cól mumèint ché la pàgina serchêda l'é vōda. L'é pusébil [[Special:Search/{{PAGENAME}}|serchêr sté tétol]] int al j êtri pàgini dal sît, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchêr int i regéster coleghê] opór [{{fullurl:{{FULLPAGENAME}}|action=edit}} mudifichêr la pàgina adèsa]</span>.",
"noarticletext-nopermission": "In cól mumèint ché la pàgina serchêda l'é vōda. L'é pusébil [[Special:Search/{{PAGENAME}}|serchêr sté tétol]] int al j êtri pàgini dal sît o<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchêr int i regéster coleghê] <span>, mó an 't gh'ê mìa al permès ed fêr cla pàgina ché.",
"missing-revision": "La revişiòun #$1 'd la pagina \"{{FULLPAGENAME}}\" l' an gh'è mìa. Còst, ed sôlit, a sucēd mèint'r as va drē a 'n colegamèint a 'na pàgina scanşlêda, in 'na stòria, di lavōr fât, mìa arnuvêda. I particulêr a 's pōlen catêr int al [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} regéster dal scanşladûri].",
"previewnote": "'''Να θυμάστε ότι αυτή είναι μόνο μια προεπισκόπηση.'''\nΟι αλλαγές σας δεν έχουν ακόμη αποθηκευτεί!",
"continue-editing": "Μεταβείτε στην περιοχή επεξεργασίας",
"previewconflict": "Αυτή η προεπισκόπηση απεικονίζει το κείμενο στην επάνω περιοχή επεξεργασίας κειμένου, όπως θα εμφανιστεί εάν επιλέξετε να το αποθηκεύσετε.",
- "session_fail_preview": "'''Συγγνώμη! Δεν μπορούσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.\nΠαρακαλώ προσπαθήστε ξανά. Αν δεν δουλεύει ξανά, δοκιμάστε να αποσυνδεθείτε και να συνδεθείτε πάλι.'''",
+ "session_fail_preview": "'''Συγγνώμη! Δεν μπορούσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.\nΠαρακαλώ προσπαθήστε ξανά. Αν δεν δουλεύει ξανά, δοκιμάστε να [[Special:UserLogout|αποσυνδεθείτε]] και να συνδεθείτε πάλι.'''",
"session_fail_preview_html": "'''Λυπούμαστε! Δεν μπορέσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.'''\n\n''Επειδή το {{SITENAME}} επιτρέπει την εισαγωγή ακατέργαστου HTML, η προεπισκόπηση είναι κρυμμένη ως προφύλαξη ενάντια σε επιθέσεις με Javascript.''\n\n'''Αν αυτή είναι μια έγκυρη προσπάθεια επεξεργασίας, παρακαλώ προσπαθήστε ξανά. Αν πάλι δε δουλεύει, δοκιμάστε να αποσυνδεθείτε και να συνδεθείτε πάλι.'''",
"token_suffix_mismatch": "'''Η επεξεργασία σας απορρίφθηκε γιατί το πρόγραμμα-πελάτη σας κατακρεούργησε τους χαρακτήρες στίξης στο κουπόνι επεξεργασίας. Η επεξεργασία απορρίφθηκε για να αποφευχθεί η παραφθορά του κειμένου της σελίδας.\nΑυτό μερικές φορές συμβαίνει όταν χρησιμοποιείται ένας ανώνυμος διακομιστής μεσολάβησης διαθέσιμος μέσω του παγκόσμιου ιστού με σφάλματα.'''",
"edit_form_incomplete": "'''Ορισμένα τμήματα της φόρμας επεξεργασίας δεν έφθασαν στο διακομιστή. Ελέγξτε ότι οι αλλαγές σας είναι άθικτες και προσπαθήστε ξανά.'''",
"uploadstash-summary": "Η σελίδα παρέχει πρόσβαση σε αρχεία που είναι επιφορτωμένα (ή στη διαδικασία της επιφόρτωσης) αλλά δεν έχει ακόμη δημοσιευθεί για το wiki. Αυτά τα αρχεία δεν είναι ορατά σε οποιονδήποτε, αλλά στο χρήστη που τα επιφόρτωσε.",
"uploadstash-clear": "Καθαρά διατηρημένα αρχεία",
"uploadstash-nofiles": "Δεν έχετε κρυμμένα αρχεία.",
- "uploadstash-badtoken": "Î\95κÏ\84ÎλεÏ\83η Ï\84ηÏ\82 εν λÏ\8cγÏ\89 ενÎÏ\81γειαÏ\82 ήÏ\84αν ανεÏ\80ιÏ\84Ï\85Ï\87ήÏ\82, ίÏ\83Ï\89Ï\82 εÏ\80ειδή Ï\84α διαÏ\80ιÏ\83Ï\84εÏ\85Ï\84ήÏ\81ιά εÏ\80εξεÏ\81γαÏ\83ίαÏ\82 Ï\83αÏ\82 ÎÏ\87οÏ\85ν λήξει. Î\94οκίμαστε ξανά.",
- "uploadstash-errclear": "Î\97 εκκαθάÏ\81ιÏ\83η Ï\84Ï\89ν αÏ\81Ï\87είÏ\89ν ήÏ\84αν ανεÏ\80ιÏ\84Ï\85Ï\87ήÏ\82.",
+ "uploadstash-badtoken": "Î\95κÏ\84ÎλεÏ\83η Ï\84ηÏ\82 εν λÏ\8cγÏ\89 ενÎÏ\81γειαÏ\82 αÏ\80ÎÏ\84Ï\85Ï\87ε, ίÏ\83Ï\89Ï\82 εÏ\80ειδή Ï\84α διαÏ\80ιÏ\83Ï\84εÏ\85Ï\84ήÏ\81ιά εÏ\80εξεÏ\81γαÏ\83ίαÏ\82 Ï\83αÏ\82 ÎÏ\87οÏ\85ν λήξει. ΠαÏ\81ακαλοÏ\8dμε δοκιμάστε ξανά.",
+ "uploadstash-errclear": "Î\97 εκκαθάÏ\81ιÏ\83η Ï\84Ï\89ν αÏ\81Ï\87είÏ\89ν αÏ\80ÎÏ\84Ï\85Ï\87ε.",
"uploadstash-refresh": "Ανανεώσετε τη λίστα των αρχείων",
"invalid-chunk-offset": "Άκυρο κομμάτι όφσετ",
"img-auth-accessdenied": "Δεν επετράπη η πρόσβαση",
"delete-toobig": "Αυτή η σελίδα έχει μεγάλο ιστορικό τροποποιήσεων, πάνω από $1 {{PLURAL:$1|τροποποίηση|τροποποιήσεις}}.\nΗ διαγραφή τέτοιων σελίδων έχει περιοριστεί για την αποφυγή τυχαίας αναστάτωσης του {{SITENAME}}.",
"delete-warning-toobig": "Αυτή η σελίδα έχει μεγάλο ιστορικό τροποποιήσεων, πάνω από $1 {{PLURAL:$1|τροποποίηση|τροποποιήσεις}}.\nΗ διαγραφή της μπορεί να αναστατώσει τη λειτουργία της βάσης δεδομένων του {{SITENAME}}. Συνιστούμε μεγάλη προσοχή.",
"deleteprotected": "Δεν μπορείτε να διαγράψετε αυτή τη σελίδα επειδή είναι προστατευόμενη.",
- "deleting-backlinks-warning": "\"'Προσοχή:\"' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Άλλες σελίδες]] συνδέουν ή ενσωματώνουν τη σελίδα που πρόκειται να διαγράψετε.",
+ "deleting-backlinks-warning": "<strong>Προσοχή:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Άλλες σελίδες]] συνδέουν ή ενσωματώνουν τη σελίδα που πρόκειται να διαγράψετε.",
"rollback": "Επαναφορά επεξεργασιών",
"rollbacklink": "αναστροφή",
"rollbacklinkcount": "Επαναφορά $1 {{PLURAL:$1|επεξεργασίας|επεξεργασιών}}",
"undeletedrevisions": "{{PLURAL:$1|τροποποίηση|τροποποιήσεις}} αποκαταστάθηκαν",
"undeletedrevisions-files": "$1 {{PLURAL:$1|αναθεώρηση|αναθεωρήσεις}} και $2 {{PLURAL:$2|αρχείο|αρχεία}} επαναφέρθηκαν",
"undeletedfiles": "$1 {{PLURAL:$1|αρχείο|αρχεία}} επαναφέρθηκαν",
- "cannotundelete": "Î\97 αναίÏ\81εÏ\83η διαγÏ\81αÏ\86ήÏ\82 αÏ\80ÎÏ\84Ï\85Ï\87ε: $1",
+ "cannotundelete": "Î\9cεÏ\81ικÎÏ\82 ή Ï\8cλεÏ\82 οι αναιÏ\81ÎÏ\83ειÏ\82 διαγÏ\81αÏ\86ήÏ\82 αÏ\80ÎÏ\84Ï\85Ï\87αν: $1",
"undeletedpage": "'''Η $1 έχει επαναφερθεί'''\n\nΣυμβουλευτείτε το [[Special:Log/delete|αρχείο καταγραφής διαγραφών]] για ένα μητρώο των πρόσφατων διαγραφών και επαναφορών.",
"undelete-header": "Δείτε [[Special:Log/delete|το αρχείο καταγραφής διαγραφών]] για πρόσφατα διαγεγραμμένες σελίδες.",
"undelete-search-title": "Αναζήτηση διαγεγραμμένων σελίδων",
"sp-contributions-newbies-sub": "Για νέους λογαριασμούς",
"sp-contributions-newbies-title": "Συνεισφορές χρηστών για νέους λογαριασμούς",
"sp-contributions-blocklog": "αρχείο καταγραφών φραγών",
- "sp-contributions-suppresslog": "διαγεγραμμένες συνεισφορές χρήστη",
+ "sp-contributions-suppresslog": "διαγεγραμμένες συνεισφορές {{GENDER:$1|χρήστη|χρήστριας}}",
"sp-contributions-deleted": "διαγεγραμμένες συνεισφορές χρήστη",
"sp-contributions-uploads": "ανεβάσματα αρχείων",
"sp-contributions-logs": "καταγραφές",
"watchlistedit-raw-done": "Η λίστα παρακολούθησής σας ενημερώθηκε.",
"watchlistedit-raw-added": "{{PLURAL:$1|1 σελίδα|$1 σελίδες}} προστέθηκαν:",
"watchlistedit-raw-removed": "{{PLURAL:$1|1 σελίδα|$1 σελίδες}} αφαιρέθηκαν:",
- "watchlistedit-clear-title": "Î\95κκαθαÏ\81ιÏ\83μÎνη λίÏ\83Ï\84α παρακολούθησης",
+ "watchlistedit-clear-title": "Î\95κκαθάÏ\81ιÏ\83η λίÏ\83Ï\84αÏ\82 παρακολούθησης",
"watchlistedit-clear-legend": "Εκκαθάριση λίστας παρακολούθησης",
"watchlistedit-clear-explain": "Όλοι οι τίτλοι θα αφαιρεθούν από τη λίστα παρακολούθησής σας",
"watchlistedit-clear-titles": "Τίτλοι:",
"version-libraries-license": "Άδεια χρήσης",
"version-libraries-description": "Περιγραφή",
"version-libraries-authors": "Δημιουργοί",
- "redirect": "Ανακατεύθυνση κατά αρχείο, χρήστη, σελίδα ή αναγνωριστικό αναθεώρησης",
+ "redirect": "Ανακατεύθυνση κατά αρχείο, χρήστη, σελίδα, αναγνωριστικό αναθεώρησης ή αρχείο καταγραφής ID",
"redirect-submit": "Μετάβαση",
"redirect-lookup": "Αναζήτηση:",
"redirect-value": "Τιμή:",
"tags-delete-submit": "Μη αναστρέψιμη διαγραφή αυτής της ετικέτας",
"tags-delete-not-found": "Η ετικέτα «$1» δεν υπάρχει.",
"tags-delete-too-many-uses": "Η ετικέτα «$1» εφαρμόζεται σε πάνω από {{PLURAL:$2|μία αναθεώρηση|$2 αναθεωρήσεις}}, που σημαίνει ότι δεν μπορεί να διαγραφεί.",
- "tags-delete-warnings-after-delete": "Η ετικέτα «$1» διαγράφηκε με επιτυχία, αλλά {{PLURAL:$2|προέκυψε η ακόλουθη προειδοποίηση|προέκυψαν οι ακόλουθες προειδοποιήσεις}}:",
+ "tags-delete-warnings-after-delete": "Η ετικέτα «$1» διαγράφηκε, αλλά {{PLURAL:$2|προέκυψε η ακόλουθη προειδοποίηση|προέκυψαν οι ακόλουθες προειδοποιήσεις}}:",
"tags-delete-no-permission": "Δεν έχετε άδεια να διαχειριστείτε ετικέτες αλλαγής.",
"tags-activate-title": "Ενεργοποίηση ετικέτας",
"tags-activate-question": "Πρόκειται να ενεργοποιήσετε την ετικέτα «$1».",
"tags-edit-reason": "Αιτία:",
"tags-edit-revision-submit": "Εφαρμογή αλλαγών σε {{PLURAL:$1|αυτή την αναθεώρηση|$1 αναθεωρήσεις}}",
"tags-edit-logentry-submit": "Εφαρμογή αλλαγών σε {{PLURAL:$1|αυτήν την καταχώρηση|$1 καταχωρήσεις}} του αρχείου καταγραφής",
- "tags-edit-success": "Οι αλλαγές εφαρμόστηκαν με επιτυχία.",
+ "tags-edit-success": "Οι αλλαγές εφαρμόστηκαν.",
"tags-edit-failure": "Οι αλλαγές δεν ήταν δυνατόν να εφαρμοστούν:\n$1",
"tags-edit-nooldid-title": "Μη έγκυρη αναθεώρηση προορισμού",
"tags-edit-none-selected": "Παρακαλώ επιλέξτε τουλάχιστον μία ετικέτα για να προσθέσετε ή να αφαιρέσετε.",
"yourpasswordagain": "Retype password:",
"createacct-yourpasswordagain": "Confirm password",
"createacct-yourpasswordagain-ph": "Enter password again",
- "remembermypassword": "Remember my login on this browser (for a maximum of $1 {{PLURAL:$1|day|days}})",
"userlogin-remembermypassword": "Keep me logged in",
"userlogin-signwithsecure": "Use secure connection",
"cannotloginnow-title": "Cannot log in now",
"file-thumbnail-no": "The filename begins with <strong>$1</strong>.\nIt seems to be an image of reduced size <em>(thumbnail)</em>.\nIf you have this image in full resolution upload this one, otherwise change the filename please.",
"fileexists-forbidden": "A file with this name already exists, and cannot be overwritten.\nIf you still want to upload your file, please go back and use a new name.\n[[File:$1|thumb|center|$1]]",
"fileexists-shared-forbidden": "A file with this name exists already in the shared file repository.\nIf you still want to upload your file, please go back and use a new name.\n[[File:$1|thumb|center|$1]]",
+ "fileexists-no-change": "The upload is an exact duplicate of the current version of <strong>[[:$1]]</strong>.",
+ "fileexists-duplicate-version": "The upload is an exact duplicate of {{PLURAL:$2|an older version|older versions}} of <strong>[[:$1]]</strong>.",
"file-exists-duplicate": "This file is a duplicate of the following {{PLURAL:$1|file|files}}:",
"file-deleted-duplicate": "A file identical to this file ([[:$1]]) has previously been deleted.\nYou should check that file's deletion history before proceeding to re-upload it.",
"file-deleted-duplicate-notitle": "A file identical to this file has previously been deleted, and the title has been suppressed.\nYou should ask someone with the ability to view suppressed file data to review the situation before proceeding to re-upload it.",
"filerevert-submit": "Revert",
"filerevert-success": "<strong>[[Media:$1|$1]]</strong> has been reverted to the [$4 version as of $3, $2].",
"filerevert-badversion": "There is no previous local version of this file with the provided timestamp.",
+ "filerevert-identical": "The current version of the file is already identical to the selected one.",
"filedelete": "Delete $1",
"filedelete-legend": "Delete file",
"filedelete-intro": "You are about to delete the file <strong>[[Media:$1|$1]]</strong> along with all of its history.",
"action-import": "importar páginas desde otro wiki",
"action-importupload": "importar páginas mediante la carga de un archivo",
"action-patrol": "marcar ediciones de otros como verificadas",
- "action-autopatrol": "tener tus ediciones marcadas como verificadas",
+ "action-autopatrol": "marcar como verificadas tus propias ediciones",
"action-unwatchedpages": "ver la lista de páginas no vigiladas",
"action-mergehistory": "fusionar el historial de esta página",
"action-userrights": "modificar todos los permisos de usuario",
"logentry-delete-revision": "$1 {{GENDER:$2|modificó}} la visibilidad de {{PLURAL:$5|una revisión |$5 revisiones}} en la página $3: $4",
"logentry-delete-event-legacy": "$1 ha {{GENDER:$2|cambiado}} la visibilidad de eventos del registro en $3",
"logentry-delete-revision-legacy": "$1 ha {{GENDER:$2|cambiado}} la visibilidad de las revisiones en la página $3",
- "logentry-suppress-delete": "$1 {{GENDER:$2|borró}} la página $3",
+ "logentry-suppress-delete": "$1 {{GENDER:$2|suprimió}} la página $3",
"logentry-suppress-event": "$1 {{GENDER:$2|modificó}} secretamente la visibilidad de {{PLURAL:$5|un evento|$5 eventos}} del registro en $3: $4",
"logentry-suppress-revision": "$1 {{GENDER:$2|modificó}} secretamente la visibilidad de {{PLURAL:$5|una edición|$5 ediciones}} en la página $3: $4",
"logentry-suppress-event-legacy": "$1 {{GENDER:$2|modificó}} secretamente la visibilidad de los eventos del registro en $3",
"tog-watchdefault": "Lisa jälgimisloendisse minu muudetud leheküljed ja failid",
"tog-watchmoves": "Lisa jälgimisloendisse minu teisaldatud leheküljed ja failid",
"tog-watchdeletion": "Lisa jälgimisloendisse minu kustutatud leheküljed ja failid",
+ "tog-watchuploads": "Lisa jälgimisloendisse uued failid, mille olen üles laadinud",
"tog-watchrollback": "Lisa jälgimisloendisse leheküljed, kus olen muudatuse tühistanud",
"tog-minordefault": "Märgi kõik parandused vaikimisi pisiparandusteks",
"tog-previewontop": "Näita eelvaadet toimetamiskasti ees",
"minoredit": "See on pisiparandus",
"watchthis": "Jälgi seda lehekülge",
"savearticle": "Salvesta",
+ "savechanges": "Salvesta",
"publishpage": "Avalda lehekülg",
"publishchanges": "Avalda muudatused",
"preview": "Eelvaade",
"undeletedrevisions": "$1 {{PLURAL:$1|redaktsioon|redaktsiooni}} taastatud",
"undeletedrevisions-files": "{{PLURAL:$1|1 redaktsioon|$1 redaktsiooni}} ja {{PLURAL:$2|1 fail|$2 faili}} taastatud",
"undeletedfiles": "{{PLURAL:$1|1 fail|$1 faili}} taastatud",
- "cannotundelete": "Taastamine ebaõnnestus:\n$1",
+ "cannotundelete": "Taastamine ebaõnnestus osaliselt või täielikult:\n$1",
"undeletedpage": "'''$1 on taastatud'''\n\n[[Special:Log/delete|Kustutamise logist]] võib leida loendi viimastest kustutamistest ja taastamistest.",
"undelete-header": "Hiljuti kustutatud leheküljed leiad [[Special:Log/delete|kustutamislogist]].",
"undelete-search-title": "Kustutatud lehekülgede otsimine",
"sp-contributions-newbies-sub": "Uute kontode kaastöö",
"sp-contributions-newbies-title": "Uute kasutajate kaastöö",
"sp-contributions-blocklog": "blokeerimised",
- "sp-contributions-suppresslog": "varjatud kaastöö",
- "sp-contributions-deleted": "kustutatud kaastöö",
+ "sp-contributions-suppresslog": "{{GENDER:$1|varjatud}} kaastöö",
+ "sp-contributions-deleted": "{{GENDER:$1|kustutatud}} kaastöö",
"sp-contributions-uploads": "üleslaadimised",
"sp-contributions-logs": "logid",
"sp-contributions-talk": "arutelu",
"createacct-another-realname-tip": "Benetako izena hautazkoa da.\nEmatea erabakitzen baduzu hori erabiliko da lanaren atribuzioa egiterako garaian.",
"pt-login": "Saioa hasi",
"pt-login-button": "Saioa hasi",
+ "pt-login-continue-button": "Konexioa jarraitu",
"pt-createaccount": "Sortu kontua",
"pt-userlogout": "Saioa itxi",
"php-mail-error-unknown": "PHPren mail() funtzioan arazo ezezagun bat egon da.",
"resetpass_submit": "Pasahitza definitu eta saioa hasi",
"changepassword-success": "Zure pasahitza aldatu da!",
"changepassword-throttled": "Saioa hasteko saiakera gehiegi egin berri dituzu.\nBerriro saiatu aurretik $1 itxoin, mesedez.",
+ "botpasswords": "Bot pasahitzak",
+ "botpasswords-disabled": "Bot pasahitzak desgaituak daude.",
"botpasswords-label-appid": "Bot izena:",
"botpasswords-label-create": "Sortu",
"botpasswords-label-update": "Eguneratu",
"userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" lankidea ez dago erregistatuta. Mesedez, konprobatu orri hau editatu/sortu nahi duzun.",
"userpage-userdoesnotexist-view": "\"$1\" erabiltzaile-kontua ez dago erregistraturik.",
"blocked-notice-logextract": "Erabiltzaile hau blokeatuta dago une honetan.\nAzken blokeoaren erregistroa ageri da behean, erreferentzia gisa:",
- "clearyourcache": "'''Oharra:''' Gorde ondoren, zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko.\n* '''Firefox / Safari:''' ''Shift'' tekla sakatu birkargatzeko momentuan, edo ''Ctrl-Shift-R'' edo ''Crtl-F5'' sakatu (''⌘-R''' Mac batean)\n* '''Google Chrome:''' ''Ctrl-Shift-R'' sakatu (''⌘-Shift-R'' Mac batean)\n* '''Internet Explorer:''' ''Ctrl'' tekla sakatu birkargatzeko momentuan, edo ''Ctrl-F5'' sakatu\n* '''Opera''' erabiltzaileek ''Tresnak → Hobespenak'' atalera joan eta katxea garbitzeko aukera hautatu",
+ "clearyourcache": "<strong>Oharra:</strong> Gorde ondoren, zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko.\n* <strong>Firefox / Safari:</strong> <em>Shift</em> tekla sakatu birkargatzeko momentuan, edo <em>Ctrl-Shift-R</em> edo <em>Crtl-F5</em> sakatu (<em>⌘-R</em> Mac batean)\n* <strong>Google Chrome:</strong> <em>Ctrl-Shift-R </em> sakatu (<em>⌘-Shift-R</em> Mac batean)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> tekla sakatu birkargatzeko momentuan, edo <em>Ctrl-F5</em> sakatu\n* <strong>Opera</strong> erabiltzaileek <em>Tresnak → Hobespenak</em> atalera joan eta katxea garbitzeko aukera hautatu",
"usercssyoucanpreview": "'''Laguntza:''' Zure CSS berria gorde aurretik probatzeko \"{{int:showpreview}}\" botoia erabili.",
"userjsyoucanpreview": "'''Laguntza:''' Zure JS berria gorde aurretik probatzeko \"{{int:showpreview}}\" botoia erabili.",
"usercsspreview": "'''Ez ahaztu zure CSS kodea aurreikusten zabiltzala.'''\n'''Oraindik gorde gabe dago!'''",
"previewnote": "'''Gogoratu hau aurrikuspen bat dela.'''\nZure aldaketak ez dira oraindik gorde!",
"continue-editing": "Edizio-eremura joan",
"previewconflict": "Aurreikuspenak aldaketen koadroan idatzitako testua erakusten du, gorde ondoren agertuko den bezala.",
- "session_fail_preview": "'''Sentitzen dugu! Ezin izan da zure aldaketa prozesatu, saioko datu batzuen galera dela-eta. Mesedez, saiatu berriz. Arazoak jarraitzen badu, saiatu saioa amaitu eta berriz hasten.'''",
+ "session_fail_preview": "'''Sentitzen dugu! Ezin izan da zure aldaketa prozesatu, saioko datu batzuen galera dela-eta. Mesedez, saiatu berriz. Arazoak jarraitzen badu, saiatu [[Special:UserLogout|saioa amaitu]] eta berriz hasten.'''",
"session_fail_preview_html": "'''Sentitzen dugu! Ezin izan dugu zure aldaketa burutu, saio datu galera bat medio.'''\n\n''Wiki honek HTML kodea onartzen duenez, aurreikuspena ezgaituta dago JavaScript erasoak saihestu asmoz.''\n\n'''Aldaketa saiakera hau zuzena baldin bada, saiatu berriro mesedez. Arazoak jarraitzen badu, saiatu saioa itxi eta berriz hasten.'''",
"token_suffix_mismatch": "'''Zure aldaketa ezeztatua izan da zure bezeroak puntuazio-karaktereak itxuragabetu dituelako.\nAldaketa ezeztatua izan da testuaren galtzea galarazteko.\nHau batzuetan gertatzen da buggyan oinarritutako web proxy zerbitzua erabiltzean.'''",
"edit_form_incomplete": "'''Aldaketa formularioaren atal batzuk ez dira iritsi zerbitzarira; bi aldiz ziurtatu zure aldaketak osorik daudela eta berriro saiatu.'''",
"undeletedrevisions": "{{PLURAL:$1|Berrikuspen 1 leheneratu da|$1 berrikuspen leheneratu dira}}",
"undeletedrevisions-files": "{{PLURAL:$1|berrikuspen|berrikuspen}} eta {{PLURAL:$2|fitxategi|fitxategi}} leheneratu dira",
"undeletedfiles": "{{PLURAL:$1|fitxategi|fitxategi}} leheneratu dira",
- "cannotundelete": "Ezabatutako birgaitzean akatsa: $1",
+ "cannotundelete": "Ezabatutako birgaitze betean edo hainbatetan akatsa: $1",
"undeletedpage": "'''«$1» leheneratu da'''\n\nAzken ezabatze eta leheneratzeak ikusteko, jo ezazu [[Special:Log/delete|ezabaketa erregistrora]].",
"undelete-header": "Berriki ezabatutako orriak ikusteko, jo ezazu [[Special:Log/delete|ezabaketa erregistrora]].",
"undelete-search-title": "Ezabatutako orrialdeak bilatu",
"sp-contributions-newbies-sub": "Hasiberrientzako",
"sp-contributions-newbies-title": "Lankideen ekarpenak lankide berrietn",
"sp-contributions-blocklog": "Blokeaketa erregistroa",
- "sp-contributions-suppresslog": "lankide-ekarpen ezabatuak",
+ "sp-contributions-suppresslog": "{{GENDER:$1|(r)en}} lankide-ekarpen ezabatuak",
"sp-contributions-deleted": "lankide-ekarpen ezabatuak",
"sp-contributions-uploads": "igoerak",
"sp-contributions-logs": "erregistroak",
]
},
"tog-underline": "Soulignement des liens :",
- "tog-hideminor": "Masquer les modifications mineures dans les changements récents",
- "tog-hidepatrolled": "Masquer, dans les modifications récentes, les modifications relues",
+ "tog-hideminor": "Masquer les modifications mineures dans les modifications récentes",
+ "tog-hidepatrolled": "Masquer les modifications relues dans les modifications récentes",
"tog-newpageshidepatrolled": "Masquer les pages relues dans la liste des nouvelles pages",
"tog-hidecategorization": "Masquer la catégorisation des pages",
"tog-extendwatchlist": "Étendre la liste de suivi pour afficher toutes les modifications et pas uniquement les plus récentes",
"previewerrortext": "Une erreur s’est produite lors de la tentative de prévisualisation de vos modifications.",
"blockedtitle": "L’utilisateur est bloqué.",
"blockedtext": "'''Votre compte utilisateur ou votre adresse IP a été bloqué.'''\n\nLe blocage a été effectué par $1.\nLa raison invoquée est la suivante : ''$2''.\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7.\n\nVous pouvez contacter $1 ou un autre [[{{MediaWiki:Grouppage-sysop}}|administrateur]] pour en discuter.\nVous ne pouvez utiliser la fonction « {{int:emailuser}} » que si une adresse de courriel valide est spécifiée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité n’a pas été bloquée.\nVotre adresse IP actuelle est $3 et votre identifiant de blocage est $5.\nVeuillez préciser ces indications dans toutes les requêtes que vous ferez.",
- "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n:''$2''\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité d’envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que si cette fonctionnalité n’a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez préciser ces indications dans toutes les requêtes que vous ferez.",
+ "autoblockedtext": "Votre adresse IP a été bloquée automatiquement car elle a été utilisée par un autre utilisateur, lui-même bloqué par $1.\nLa raison invoquée est :\n\n:<em>$2:</em>\n\n* Début du blocage : $8\n* Expiration du blocage : $6\n* Compte bloqué : $7\n\nVous pouvez contacter $1 ou l’un des autres [[{{MediaWiki:Grouppage-sysop}}|administrateurs]] pour discuter de ce blocage.\n\nNotez que vous ne pourrez utiliser la fonctionnalité d’envoi de courriel que si vous avez une adresse de courriel validée dans vos [[Special:Preferences|préférences]] et que cette fonctionnalité n’a pas été désactivée.\n\nVotre adresse IP actuelle est $3, et le numéro de blocage est $5.\nVeuillez préciser ces indications dans toutes les requêtes que vous ferez.",
"blockednoreason": "aucune raison donnée",
"whitelistedittext": "Vous devez vous $1 pour avoir la permission de modifier le contenu.",
"confirmedittext": "Vous devez confirmer votre adresse de courriel avant de modifier les pages.\nVeuillez entrer et valider votre adresse de courriel dans vos [[Special:Preferences|préférences]].",
"missing-revision": "La révision nº $1 de la page intitulée « {{FULLPAGENAME}} » n’existe pas.\n\nCela survient en général en suivant un lien historique obsolète vers une page qui a été supprimée.\nVous pouvez trouver plus de détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
"userpage-userdoesnotexist": "Le compte utilisateur « <nowiki>$1</nowiki> » n’est pas enregistré. Veuillez vérifier que vous voulez créer cette page.",
"userpage-userdoesnotexist-view": "Le compte utilisateur « $1 » n'est pas enregistré.",
- "blocked-notice-logextract": "Cet utilisateur est actuellement bloqué.\nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d’information :",
+ "blocked-notice-logextract": "Cet utilisateur est actuellement bloqué.\nLa dernière entrée du journal des blocages est affichée ci-dessous pour référence :",
"clearyourcache": "<strong>Note :</strong> après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.\n* <strong>Firefox / Safari :</strong> maintenez la touche <em>Maj</em> (<em>Shift</em>) en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> sur un Mac) \n* <strong>Google Chrome :</strong> appuyez sur <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> sur un Mac) \n* <strong>Internet Explorer :</strong> maintenez la touche <em>Ctrl</em> en cliquant sur le bouton <em>Actualiser</em> ou pressez <em>Ctrl-F5</em> \n* <strong>Opera :</strong> allez dans <em>Menu → Settings</em> (<em>Opera → Préférences</em> sur un Mac) et ensuite à <em>Confidentialité & sécurité → Effacer les données d’exploration → Images et fichiers en cache</em>.",
"usercssyoucanpreview": "<strong>Astuce :</strong> utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille CSS avant de l’enregistrer.",
"userjsyoucanpreview": "<strong>Astuce :</strong> utilisez le bouton « {{int:showpreview}} » pour tester votre nouvelle feuille JavaScript avant de l’enregistrer.",
"explainconflict": "Cette page a été changée après que vous ayez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\n<strong>Seul</strong> le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
"yourtext": "Votre texte",
"storedversion": "La version enregistrée",
- "nonunicodebrowser": "<strong>Attention : votre navigateur ne supporte pas l’Unicode.</strong>\nUn palliatif est en place vous permettant de modifier les pages en toute sécurité, faisant apparaître les caractères non-ASCII sous forme hexadécimale dans la boîte de modification.",
+ "nonunicodebrowser": "<strong>Attention : votre navigateur ne prend pas en charge l’Unicode.</strong>\nUn palliatif est en place vous permettant de modifier les pages en toute sécurité, faisant apparaître les caractères non-ASCII sous forme hexadécimale dans la boîte de modification.",
"editingold": "<strong>Attention : vous êtes en train de modifier une ancienne version de cette page.</strong>\nSi vous la publiez, toutes les modifications effectuées depuis cette version seront perdues.",
"yourdiff": "Différences",
"copyrightwarning": "Toutes les contributions à {{SITENAME}} sont considérées comme publiées sous les termes de la $2 (voir $1 pour plus de détails). \nSi vous ne désirez pas que vos écrits soient modifiés et distribués à volonté, merci de ne pas les soumettre ici.<br /> \nVous nous promettez aussi que vous avez écrit ceci vous-même, ou que vous l’avez copié d’une source provenant du domaine public ou d’une ressource libre similaire. \n<strong>N’UTILISEZ PAS DE TRAVAUX SOUS DROIT D’AUTEUR SANS AUTORISATION EXPRESSE !</strong>",
"large-file": "Les fichiers importés ne devraient pas dépasser $1 ; \nce fichier fait $2.",
"largefileserver": "La taille de ce fichier est supérieure au maximum autorisé par le serveur.",
"emptyfile": "Le fichier que vous voulez importer semble vide.\nCeci peut être dû à une erreur dans le nom du fichier.\nVeuillez vérifier que vous désirez vraiment importer ce fichier.",
- "windows-nonascii-filename": "Ce wiki ne supporte pas les noms de fichiers avec des caractères spéciaux.",
+ "windows-nonascii-filename": "Ce wiki ne prend pas en charge les noms de fichiers avec des caractères spéciaux.",
"fileexists": "Un fichier existe déjà sous ce nom.\nMerci de vérifier <strong>[[:$1]]</strong> si vous n'êtes pas certain{{GENDER:||e|}} de vouloir le remplacer.\n[[$1|thumb]]",
"filepageexists": "La page de description pour ce fichier a déjà été créée ici <strong>[[:$1]]</strong>, mais aucun fichier n'existe actuellement sous ce nom.\nLe résumé que vous allez spécifier n'apparaîtra pas sur la page de description.\nPour que ce soit le cas, vous devrez modifier manuellement la page. \n[[$1|thumb]]",
"fileexists-extension": "Un fichier existe avec un nom proche : [[$2|thumb]]\n* Nom du fichier à importer : <strong>[[:$1]]</strong>\n* Nom du fichier existant : <strong>[[:$2]]</strong>\nPeut-être voulez-vous utiliser un nom plus explicite ?",
"upload-form-label-not-own-work-local-generic-local": "Vous pouvez aussi essayer [[Special:Upload|la page de téléchargement par défaut]].",
"upload-form-label-own-work-message-generic-foreign": "Je comprends que je téléverse ce fichier vers un dépôt partagé. Je confirme agir en accord avec les conditions d’utilisation et les règles relatives aux licences de celui-ci.",
"upload-form-label-not-own-work-message-generic-foreign": "Si vous n’êtes pas en mesure de téléverser ce fichier de façon conforme aux règles de ce dépôt partagé, veuillez fermer cette boîte de dialogue et essayer une autre méthode.",
- "upload-form-label-not-own-work-local-generic-foreign": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si leur règles de site autorisent le téléversement du fichier.",
+ "upload-form-label-not-own-work-local-generic-foreign": "Vous pouvez également essayer d’utiliser [[Special:Upload|la page de téléversement de {{SITENAME}}]], si leurs règles autorisent le téléversement du fichier.",
"backend-fail-stream": "Impossible de lire le fichier \"$1\".",
"backend-fail-backup": "Impossible de sauvegarder le fichier \"$1\".",
"backend-fail-notexists": "Le fichier $1 n’existe pas.",
"zip-file-open-error": "Une erreur s'est produite lors de l'ouverture du fichier ZIP pour contrôle.",
"zip-wrong-format": "Le fichier spécifié n'est pas une archive ZIP.",
"zip-bad": "Le fichier est une archive ZIP corrompue ou illisible.\nIl ne peut pas être correctement vérifié pour la sécurité.",
- "zip-unsupported": "Le fichier est une archive ZIP qui utilise des caractéristiques non supportées par MediaWiki. \nSa sécurité ne peut pas être correctement vérifiée.",
+ "zip-unsupported": "Le fichier est une archive ZIP qui utilise des caractéristiques non prises en charge par MediaWiki.\nSa sécurité ne peut pas être correctement vérifiée.",
"uploadstash": "Cache d’import",
"uploadstash-summary": "Cette page donne accès aux fichiers qui sont importés (ou en cours d’importation), mais ne sont pas encore publiés dans le wiki. Ces fichiers ne sont pas encore visibles, sauf pour l’utilisateur qui les a importés.",
"uploadstash-clear": "Effacer les fichiers en cache d'import",
"uploadstash-exception": "Impossible de stocker le téléchargement dans la réserve ($1) : « $2 ».",
"invalid-chunk-offset": "Offset de segment non valide",
"img-auth-accessdenied": "Accès refusé",
- "img-auth-nopathinfo": "PATH_INFO manquant.\nVotre serveur n'est pas paramétré pour transmettre cette information.\nIl fonctionne peut-être en CGI et ne supporte pas img_auth.\nVoir : https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+ "img-auth-nopathinfo": "PATH_INFO manquant.\nVotre serveur n’est pas paramétré pour transmettre cette information.\nIl fonctionne peut-être en CGI et ne prend pas en charge img_auth.\nVoir : https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
"img-auth-notindir": "Le chemin demandé n'est pas le répertoire d'import configuré.",
"img-auth-badtitle": "Impossible de construire un titre valide à partir de « $1 ».",
"img-auth-nologinnWL": "Vous n'êtes pas connecté et « $1 » n'est pas dans la liste blanche.",
"filerevert-submit": "Rétablir",
"filerevert-success": "<strong>[[Media:$1|$1]]</strong> a été rétabli à [$4 la version du $2 à $3].",
"filerevert-badversion": "Il n'y a pas localement de version antérieure du fichier qui porte la date indiquée.",
+ "filerevert-identical": "La version actuelle du fichier est déjà identique à celle sélectionnée.",
"filedelete": "Supprimer $1",
"filedelete-legend": "Supprimer le fichier",
"filedelete-intro": "Vous êtes sur le point de supprimer <strong>[[Media:$1|$1]]</strong> ainsi que tout son historique.",
"undeletedrevisions": "$1 {{PLURAL:$1|version restaurée|versions restaurées}}",
"undeletedrevisions-files": "$1 version{{PLURAL:$1||s}} et $2 fichier{{PLURAL:$2||s}} restauré{{PLURAL:$2||s}}",
"undeletedfiles": "$1 {{PLURAL:$1|fichier restauré|fichiers restaurés}}",
- "cannotundelete": "Certaines ou toutes les restitutions ont échoué:\n$1",
+ "cannotundelete": "Certaines ou toutes les restaurations ont échoué :\n$1",
"undeletedpage": "<strong>La page $1 a été restaurée.</strong>\n\nConsultez le [[Special:Log/delete|journal des suppressions]] pour obtenir la liste des récentes suppressions et restaurations.",
"undelete-header": "Consultez le [[Special:Log/delete|journal des suppressions]] pour lister les pages récemment supprimées.",
"undelete-search-title": "Rechercher les pages supprimées",
"sp-contributions-logs": "journaux",
"sp-contributions-talk": "discuter",
"sp-contributions-userrights": "gérer les droits",
- "sp-contributions-blocked-notice": "Cet utilisateur est actuellement bloqué. \nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
- "sp-contributions-blocked-notice-anon": "Cette adresse IP est actuellement bloquée.\nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
+ "sp-contributions-blocked-notice": "Cet utilisateur est actuellement bloqué. \nLa dernière entrée du journal des blocages est affichée ci-dessous pour référence :",
+ "sp-contributions-blocked-notice-anon": "Cette adresse IP est actuellement bloquée.\nLa dernière entrée du journal des blocages est affichée ci-dessous pour référence :",
"sp-contributions-search": "Rechercher les contributions",
"sp-contributions-username": "Adresse IP ou nom d'utilisateur :",
"sp-contributions-toponly": "Ne montrer que les contributions qui sont les dernières des articles",
"emaillink": "envoyer un courriel",
"autoblocker": "Vous avez été bloqué automatiquement parce que votre adresse IP a été récemment utilisée par « [[User:$1|$1]] ».\nLe motif fourni pour le blocage de $1 est « $2 »",
"blocklogpage": "Journal des blocages",
- "blocklog-showlog": "Cet utilisateur a été bloqué précédemment. \nLe journal des blocages est disponible ci-dessous :",
- "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et masqué précédemment. \nLe journal des masquages est disponible ci-dessous :",
+ "blocklog-showlog": "Cet utilisateur a été bloqué précédemment. \nLe journal des blocages est affiché ci-dessous pour référence :",
+ "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et masqué précédemment. \nLe journal des masquages est affiché ci-dessous pour référence :",
"blocklogentry": "a bloqué [[$1]] ; expiration : $2 $3",
"reblock-logentry": "a modifié les paramètres du blocage de [[$1]] avec une expiration au $2 $3",
"blocklogtext": "Ceci est le journal des actions de blocage et déblocage d’utilisateurs.\nLes adresses IP automatiquement bloquées ne sont pas listées.\nConsultez la [[Special:BlockList|liste des blocages]] pour voir les bannissements et blocages effectivement en cours.",
"selfmove": "Les titres d'origine et de destination sont les mêmes ;\nimpossible de renommer une page sur elle-même.",
"immobile-source-namespace": "Vous ne pouvez pas renommer les pages dans l'espace de noms « $1 »",
"immobile-target-namespace": "Vous ne pouvez pas renommer des pages vers l’espace de noms « $1 ».",
- "immobile-target-namespace-iw": "Les destinations interwikis ne sont pas une cible valide pour les déplacements.",
+ "immobile-target-namespace-iw": "Un lien interwiki n’est pas une cible valide pour un renommage de page.",
"immobile-source-page": "Cette page n'est pas renommable.",
"immobile-target-page": "Il n'est pas possible de renommer la page vers ce titre.",
"bad-target-model": "La destination souhaitée utilise un autre modèle de contenu. Impossible de convertir de $1 vers $2.",
"imageinvalidfilename": "Le nom du fichier cible est incorrect",
"fix-double-redirects": "Mettre à jour les redirections pointant vers le titre original",
"move-leave-redirect": "Laisser une redirection vers le nouveau titre",
- "protectedpagemovewarning": "'''Attention :''' Cette page a été protégée afin que seuls les utilisateurs possédant les droits d'administrateur puissent la renommer. La dernière entrée du journal est affichée ci-dessous pour référence :",
- "semiprotectedpagemovewarning": "'''Note :''' Cette page a été protégée afin que seuls les utilisateurs enregistrés puissent la renommer. La dernière entrée du journal est affichée ci-dessous pour référence :",
+ "protectedpagemovewarning": "<strong>Attention :</strong> Cette page a été protégée afin que seuls les utilisateurs possédant les droits d'administrateur puissent la renommer. \nLa dernière entrée du journal est affichée ci-dessous pour référence :",
+ "semiprotectedpagemovewarning": "<strong>Note :</strong> Cette page a été protégée afin que seuls les utilisateurs enregistrés puissent la renommer. \nLa dernière entrée du journal est affichée ci-dessous pour référence :",
"move-over-sharedrepo": "[[:$1]] existe déjà sur un dépôt partagé. Renommer ce fichier rendra le fichier sur le dépôt partagé inaccessible.",
"file-exists-sharedrepo": "Le nom choisi est déjà utilisé par un fichier sur un dépôt partagé.\nChoisissez un autre nom.",
"export": "Exporter des pages",
- "exporttext": "Vous pouvez exporter en XML le texte et l’historique d’une page ou d’un ensemble de pages ; le résultat peut alors être importé dans un autre wiki utilisant le logiciel MediaWiki via la [[Special:Import|page d’importation]].\n\nPour exporter des pages, entrez leurs titres dans la boîte de texte ci-dessous, à raison d’un titre par ligne. Sélectionnez si vous désirez la version actuelle avec toutes les anciennes versions, avec les lignes de l’historique de la page, ou simplement la page actuelle avec des informations sur la dernière modification.\n\nDans ce dernier cas vous pouvez aussi utiliser un lien, tel que [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] pour la page [[{{MediaWiki:Mainpage}}]].",
+ "exporttext": "Vous pouvez exporter en XML le texte et l’historique d’une page ou d’un ensemble de pages.\nLe résultat peut alors être importé dans un autre wiki utilisant le logiciel MediaWiki via la [[Special:Import|page d’importation]].\n\nPour exporter des pages, entrez leurs titres dans la boîte de texte ci-dessous, à raison d’un titre par ligne. Sélectionnez si vous désirez la version actuelle avec toutes les anciennes versions, avec les lignes de l’historique de la page, ou simplement la page actuelle avec des informations sur la dernière modification.\n\nDans ce dernier cas vous pouvez aussi utiliser un lien, tel que [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] pour la page [[{{MediaWiki:Mainpage}}]].",
"exportall": "Exporter toutes les pages",
"exportcuronly": "Exporter uniquement la version courante, sans l’historique complet",
"exportnohistory": "----\n'''Note :''' l’exportation de l’historique complet des pages à l’aide de ce formulaire a été désactivée pour des raisons de performance.",
"export-submit": "Exporter",
"export-addcattext": "Ajouter les pages de la catégorie :",
"export-addcat": "Ajouter",
- "export-addnstext": "Ajouter des pages dans l'espace de noms :",
+ "export-addnstext": "Ajouter des pages de l'espace de noms :",
"export-addns": "Ajouter",
"export-download": "Enregistrer dans un fichier",
"export-templates": "Inclure les modèles",
- "export-pagelinks": "Inclure les pages liées à une profondeur de :",
+ "export-pagelinks": "Inclure les pages liées jusqu'à une profondeur de :",
"export-manual": "Ajouter des pages manuellement :",
"allmessages": "Messages système",
- "allmessagesname": "Nom du message",
+ "allmessagesname": "Nom",
"allmessagesdefault": "Message par défaut",
"allmessagescurrent": "Message actuel",
"allmessagestext": "Ceci est la liste des messages système disponibles dans l’espace de noms MediaWiki.\nVeuillez visiter la [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Régionalisation de MediaWiki] et [https://translatewiki.net/ translatewiki.net] si vous désirez contribuer à la régionalisation générique de MediaWiki.",
- "allmessagesnotsupportedDB": "Cette page '''{{ns:special}}:Allmessages''' n'est pas utilisable car '''$wgUseDatabaseMessages''' a été désactivé.",
+ "allmessagesnotsupportedDB": "Cette page n’est pas utilisable car <strong>$wgUseDatabaseMessages</strong> a été désactivé.",
"allmessages-filter-legend": "Filtrer",
"allmessages-filter": "Filtrer par état de modification :",
"allmessages-filter-unmodified": "Non modifié",
"thumbnail_invalid_params": "Paramètres de la miniature incorrects",
"thumbnail_toobigimagearea": "Fichier avec des dimensions supérieures à $1",
"thumbnail_dest_directory": "Impossible de créer le répertoire de destination",
- "thumbnail_image-type": "Type d'image non supporté",
+ "thumbnail_image-type": "Type d’image non pris en charge",
"thumbnail_gd-library": "Configuration incomplète de la bibliothèque GD : fonction $1 introuvable",
"thumbnail_image-missing": "Le fichier suivant est introuvable : $1",
"thumbnail_image-failure-limit": "Il y a eu récemment trop de tentatives échouées ($1 ou plus) pour restituer cette vignette. Veuillez réessayer ultérieurement.",
"import-mapping-subpage": "Importer comme sous-pages de la page suivante :",
"import-upload-filename": "Nom du fichier :",
"import-comment": "Commentaire :",
- "importtext": "Veuillez exporter le fichier depuis le wiki d'origine en utilisant son [[Special:Export|outil d'exportation]].\nSauvegardez-le sur votre disque dur puis importez-le ici.",
+ "importtext": "Veuillez exporter le fichier depuis le wiki d’origine en utilisant l’[[Special:Export|outil d'exportation]].\nSauvegardez-le sur votre disque dur puis importez-le ici.",
"importstart": "Importation des pages…",
"import-revision-count": "$1 version{{PLURAL:$1||s}}",
"importnopages": "Aucune page à importer.",
"importuploaderrortemp": "L'import du fichier a échoué.\nUn dossier temporaire est manquant.",
"import-parse-failure": "Échec lors de l'analyse du XML à importer",
"import-noarticle": "Aucune page à importer !",
- "import-nonewrevisions": "Aucune révision importée (toutes étaient déjà présentes, ou ignorées du fait d’erreurs).",
+ "import-nonewrevisions": "Aucune révision importée (toutes étaient soit déjà présentes, soit ignorées du fait d’erreurs).",
"xml-error-string": "$1 à la ligne $2, colonne $3 (octet $4) : $5",
"import-upload": "Import de données XML",
"import-token-mismatch": "Perte des données de session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayez</strong>.\nSi cela ne fonctionne toujours pas, essayez de [[Special:UserLogout|vous déconnecter]] et reconnectez-vous, et vérifiez que votre navigateur accepte les cookies de ce site.",
"import-error-special": "La page « $1 » n’a pas été importée parce qu’elle appartient à un espace de noms spécial qui n’autorise aucune page.",
"import-error-invalid": "Page « $1 » n’a pas été importée parce que le nom sous lequel elle aurait été importée n’est pas valide sur ce wiki.",
"import-error-unserialize": "La révision $2 de la page « $1 » ne peut pas être désérialisée. La révision est indiquée comme utilisant le modèle de contenu $3 sérialisé en $4.",
- "import-error-bad-location": "La révision $2 utilisant le modèle de contenu $3 n’a pas pu être stocké sur « $1 » sur ce wiki, car ce modèle n’est pas supporté sur cette page.",
+ "import-error-bad-location": "La révision $2 utilisant le modèle de contenu $3 n’a pas pu être stockée sur « $1 » sur ce wiki, car ce modèle n’est pas pris en charge sur cette page.",
"import-options-wrong": "{{PLURAL:$2|Mauvaise option|Mauvaises options}} : <nowiki>$1</nowiki>",
"import-rootpage-invalid": "La page racine fournie est un titre non valide.",
"import-rootpage-nosubpage": "L'espace de noms « $1 » de la page racine n'autorise pas les sous-pages.",
"javascripttest-pagetext-unknownaction": "Action « $1 » inconnue.",
"javascripttest-qunit-intro": "Voir [$1 la documentation de test] sur mediawiki.org.",
"tooltip-pt-userpage": "{{GENDER:|Votre}} page utilisateur",
- "tooltip-pt-anonuserpage": "La page utilisateur de l'IP avec laquelle vous contribuez",
+ "tooltip-pt-anonuserpage": "La page utilisateur avec l'adresse IP de laquelle vous contribuez",
"tooltip-pt-mytalk": "{{GENDER:|Votre}} page de discussion",
"tooltip-pt-anontalk": "La page de discussion pour les contributions depuis cette adresse IP",
"tooltip-pt-preferences": "{{GENDER:|Vos}} préférences",
- "tooltip-pt-watchlist": "La liste des pages dont vous suivez les modifications",
+ "tooltip-pt-watchlist": "Une liste des pages dont vous suivez les modifications",
"tooltip-pt-mycontris": "La liste de {{GENDER:|vos}} contributions",
"tooltip-pt-anoncontribs": "Une liste des modifications effectuées depuis cette adresse IP",
"tooltip-pt-login": "Il est recommandé de vous identifier ; ce n'est cependant pas obligatoire.",
"tooltip-n-recentchanges": "Liste des modifications récentes sur le wiki",
"tooltip-n-randompage": "Afficher une page au hasard",
"tooltip-n-help": "Aide",
- "tooltip-t-whatlinkshere": "Liste des pages liées à celle-ci",
- "tooltip-t-recentchangeslinked": "Liste des modifications récentes des pages liées à celle-ci",
+ "tooltip-t-whatlinkshere": "Liste des pages liées qui pointent sur celle-ci",
+ "tooltip-t-recentchangeslinked": "Liste des modifications récentes des pages appelées par celle-ci",
"tooltip-feed-rss": "Flux RSS pour cette page",
"tooltip-feed-atom": "Flux Atom pour cette page",
"tooltip-t-contributions": "Voir la liste des contributions de {{GENDER:$1|cet utilisateur|cette utilisatrice}}",
"tooltip-ca-nstab-template": "Voir le modèle",
"tooltip-ca-nstab-help": "Voir la page d'aide",
"tooltip-ca-nstab-category": "Voir la page de la catégorie",
- "tooltip-minoredit": "Marquer mes modifications comme mineures",
+ "tooltip-minoredit": "Marquer ceci comme modification mineure",
"tooltip-save": "Enregistrer vos modifications",
"tooltip-publish": "Publier vos modifications",
"tooltip-preview": "Merci de prévisualiser vos modifications avant de les publier",
- "tooltip-diff": "Affiche les modifications que vous avez apportées au texte",
- "tooltip-compareselectedversions": "Afficher les différences entre deux versions de cette page",
+ "tooltip-diff": "Afficher les modifications que vous avez apportées au texte",
+ "tooltip-compareselectedversions": "Afficher les différences entre les deux versions selectionnées de cette page",
"tooltip-watch": "Ajouter cette page à votre liste de suivi",
"tooltip-watchlistedit-normal-submit": "Enlever les titres",
"tooltip-watchlistedit-raw-submit": "Mise à jour de la liste de suivi",
"tooltip-recreate": "Recréer la page même si celle-ci a été effacée",
"tooltip-upload": "Démarrer l'import",
- "tooltip-rollback": "« Révoquer » annule en un clic la ou les modification(s) de cette page par son dernier contributeur.",
+ "tooltip-rollback": "« Révoquer » annule en un clic la ou les modification(s) de cette page réalisées par son dernier contributeur",
"tooltip-undo": "« Annuler » rétablit la modification précédente et ouvre la fenêtre de modification en mode prévisualisation. Il est possible d’ajouter une raison dans le résumé.",
"tooltip-preferences-save": "Sauvegarder les préférences",
"tooltip-summary": "Entrez un bref résumé",
"htmlform-title-not-exists": "$1 n’existe pas",
"htmlform-user-not-exists": "<strong>$1</strong> n’existe pas.",
"htmlform-user-not-valid": "<strong>$1</strong> n’est pas un nom d’utilisateur valide.",
- "sqlite-has-fts": "$1 avec recherche en texte intégral supportée",
- "sqlite-no-fts": "$1 sans recherche en texte intégral supportée",
+ "sqlite-has-fts": "$1 avec recherche en texte intégral prise en charge",
+ "sqlite-no-fts": "$1 sans recherche en texte intégral prise en charge",
"logentry-delete-delete": "$1 {{GENDER:$2|a supprimé}} la page $3",
"logentry-delete-restore": "$1 {{GENDER:$2|a restauré}} la page $3",
"logentry-delete-event": "$1 {{GENDER:$2|a modifié}} la visibilité {{PLURAL:$5|d'un événement du journal|de $5 événements du journal}} sur $3: $4",
"filerevert-submit": "Reverter",
"filerevert-success": "Reverteuse \"'''[[Media:$1|$1]]'''\" á [$4 versión do $2 ás $3].",
"filerevert-badversion": "Non existe unha versión local anterior deste ficheiro coa data e hora indicadas.",
+ "filerevert-identical": "A versión actual do ficheiro é igual á seleccionada.",
"filedelete": "Borrar \"$1\"",
"filedelete-legend": "Eliminar un ficheiro",
"filedelete-intro": "Está a piques de eliminar o ficheiro \"'''[[Media:$1|$1]]'''\" xunto con todo o seu historial.",
"filerevert-submit": "שחזור",
"filerevert-success": "<strong>[[Media:$1|$1]]</strong> שוחזר ל[$4 גרסה מ־$3, $2].",
"filerevert-badversion": "אין גרסה מקומית קודמת של הקובץ שהועלתה בתאריך המבוקש.",
+ "filerevert-identical": "הגרסה הנוכחית של הקובץ כבר זהה לגרסה שנבחרה.",
"filedelete": "מחיקת $1",
"filedelete-legend": "מחיקת קובץ",
"filedelete-intro": "אתם עומדים למחוק את הקובץ <strong>[[Media:$1|$1]]</strong> יחד עם כל היסטוריית הגרסאות שלו.",
"minoredit": "Սա չնչին խմբագրում է",
"watchthis": "Հսկել այս էջը",
"savearticle": "Հիշել էջը",
- "publishpage": "Հիշել էջը",
+ "publishpage": "Հիշել փոփոխությունները",
"publishchanges": "Հիշել փոփոխությունները",
"preview": "Նախադիտում",
"showpreview": "Նախադիտել",
"publishchanges": "Ipablaak dagiti binaliwan",
"preview": "Ipadas",
"showpreview": "Ipakita ti ipadas",
- "showdiff": "Ipakita dagiti sinukatan",
+ "showdiff": "Ipakita dagiti binaliwan",
"blankarticle": "<strong>Ballaag:</strong> Ti panid a parpatuatem ket blanko.\nNo pindutem manen ti \"{{int:savearticle}}\", ti panid ket mapartuatto nga awan ti ania man a linaon.",
"anoneditwarning": "<strong>Ballaag:</strong> Saanka a nakastrek. Ti IP a pagtaengan ket publikonto a makita nga agaramidka iti ania man a panagurnos. No <strong>[$1 sumrekka]</strong> wenno <strong>[$2 agpartuatka iti pakabilangan]</strong>, dagiti inurnosmo ket maitunosto iti naganmo nga agar-aramat, ken dagiti dadduma pay a pagimbagan.",
"anonpreviewwarning": "<em>Saanka a nakastrek. Ti panagidulin ket agirehistro ti IP a pagtaengam kadagitoy a pakasaritaan ti panagurnos iti daytoy a panid.</em>",
"tooltip-ca-nstab-template": "Kitaen ti plantilia",
"tooltip-ca-nstab-help": "Kitaen ti panid ti tulong",
"tooltip-ca-nstab-category": "Kitaen ti panid ti kategoria",
- "tooltip-minoredit": "Markaan daytoy a kas bassit a panag-urnos",
- "tooltip-save": "Idulin dagiti sinukatam",
+ "tooltip-minoredit": "Markaan daytoy a kas bassit a panagurnos",
+ "tooltip-save": "Idulin dagiti binaliwam",
"tooltip-publish": "Ipablaak dagiti binaliwam",
- "tooltip-preview": "Ipadas dagiti sinukatam, pangngaasi nga usarem daytoy sakbay nga idulin ti panid!",
- "tooltip-diff": "Ipakita no ania dagiti sinukatan nga inaramidmo iti testo",
+ "tooltip-preview": "Ipadas dagiti binaliwam. Pangngaasi nga usaren daytoy sakbay nga idulin ti panid.",
+ "tooltip-diff": "Ipakita no ania dagiti binaliwan nga inaramidmo iti teksto",
"tooltip-compareselectedversions": "Kitaen ti naggidiatan dagiti dua a napili a bersion iti daytoy a panid.",
"tooltip-watch": "Inayon daytoy a panid iti listaan ti bambantayam",
"tooltip-watchlistedit-normal-submit": "Ikkaten dagiti titulo",
"minoredit": "Þetta er minniháttar breyting",
"watchthis": "Vakta þessa síðu",
"savearticle": "Vista síðu",
+ "savechanges": "Vista breytingar",
"publishpage": "Gefa út síðu",
"publishchanges": "Gefa út breytingar",
"preview": "Forskoða",
"filerevert-submit": "Ripristina",
"filerevert-success": "'''Il file [[Media:$1|$1]]''' è stato ripristinato alla [$4 versione del $2, $3].",
"filerevert-badversion": "Non esistono versioni locali precedenti del file con il timestamp richiesto.",
+ "filerevert-identical": "La versione attuale del file è già identica a quella selezionata.",
"filedelete": "Cancella $1",
"filedelete-legend": "Cancella il file",
"filedelete-intro": "Stai per cancellare il file '''[[Media:$1|$1]]''' con tutta la sua cronologia.",
"tog-watchmoves": "Wuwuh kaca lan barkas lih-lihanku nyang pawawanganku",
"tog-watchdeletion": "Wuwuh kaca lan barkas busakanku nyang pawawanganku",
"tog-watchuploads": "Wuwuh barkas anyar unggahanku nyang pawawanganku",
- "tog-watchrollback": "Wuwuh kaca sing tak wurungaké nyang pawawanganku",
+ "tog-watchrollback": "Wuwuh kaca sing takpulihaké nyang pawawanganku",
"tog-minordefault": "Tengeri kabèh besutan minangka besutan cilik sacara baku",
"tog-previewontop": "Deleng pratuduh sadurungé mbesut kothak",
"tog-previewonfirst": "Delelng pratuduh nalika mbesut pisanan",
"about": "Bab",
"article": "Kaca isi",
"newwindow": "(buka mawa jendhéla anyar)",
- "cancel": "Wurungaké",
+ "cancel": "Wurung",
"moredotdotdot": "Liyané...",
"morenotlisted": "Pratélan iki ora jangkep.",
"mypage": "Kaca",
"viewyourtext": "Sampéyan bisa ndeleng lan nyalin sumbering <strong>besutaning sampéyan</strong> ing kaca iki.",
"protectedinterface": "Kaca iki isiné tèks antarmuka sing dienggo software lan wis dikunci kanggo menghindari kasalahan.",
"editinginterface": "'''Pènget:''' Panjenengan nyunting kaca sing dianggo nyedyakaké tèks antarmuka kanggo piranti alus.\nPangowahan kaca iki bakal awèh pangaruh marang tampilan antarmuka panganggo kanggoné panganggo liya.\nKanggo terjemahan, mangga nganggo [https://translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], proyèk lokalisasi MediaWiki.",
- "translateinterface": "Kanggo nambah utawa ngowah pertalan kanggo kabèh wiki, mangga anggoa [https://translatewiki.net/ translatewiki.net] minangka proyèk palokaling MediaWiki.",
+ "translateinterface": "Saperlu nambah utawa ngowah pertalan tumrap kabèh wiki, mangga anggoa [https://translatewiki.net/ translatewiki.net] minangka proyèk panglokaling MediaWiki.",
"cascadeprotected": "Kaca iki wis direksa saka panyuntingan amerga disertakaké ing {{PLURAL:$1|kaca|kaca-kaca}} ngisor iki sing wis direksa mawa opsi \"runtun\" diaktifaké:\n$2",
"namespaceprotected": "Panjenengan ora kagungan idin kanggo nyunting kaca ing bilik nama '''$1'''.",
"customcssprotected": "Sampéyan ora dililakaké nyunting kaca CSS iki amarga kaisi pangaturan pribadi saka panganggo liya.",
"cannotchangeemail": "Alamat layang èlèktronik akun ora bisa diganti nèng wiki iki.",
"emaildisabled": "Situs iki ora bisa ngirim layang èlèktronik.",
"accountcreated": "Akun wis kagawé",
- "accountcreatedtext": "Akun panganggo kanggo [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|wicara]]) wis digawé.",
+ "accountcreatedtext": "Akun panganggo [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|rembug]]) wis digawé.",
"createaccount-title": "Gawé rékening kanggo {{SITENAME}}",
"createaccount-text": "Ana wong sing nggawé sawijining akun utawa rékening kanggo alamat e-mail panjenengan ing {{SITENAME}} ($4) mawa jeneng \"$2\" lan tembung sandi \"$3\". Panjenengan disaranaké kanggo mlebu log lan ngganti tembung sandi panjenengan saiki.\n\nPanjenengan bisa nglirwakaké pesen iki yèn akun utawa rékening iki digawé déné sawijining kaluputan.",
"login-throttled": "Panjenengan wis kakèhan njajal mlebu log.\nTulung nunggu dhisik $1 sadurungé njajal manèh.",
"page_last": "pungkasan",
"histlegend": "Kanggo mbandhingaké: tandhani kothak radhio révisi-révisi sing arep dibandhingaké lan pencèt ''Enter'' utawa tombol sing ana ing ngisor.<br />\nLegéndha: <strong>({{int:cur}})</strong> = béda karo révisi pungkasan, <strong>({{int:last}})</strong> = béda karo révisi sadurungé, <strong>{{int:minoreditletter}}</strong> = besutan cilik.",
"history-fieldset-title": "Luru sujarah",
- "history-show-deleted": "Namung sing dibusak",
- "histfirst": "suwé dhéwé",
+ "history-show-deleted": "Mligi sing dibusak",
+ "histfirst": "lawas dhéwé",
"histlast": "anyar dhéwé",
"historysize": "($1 {{PLURAL:$1|bét|bét}})",
"historyempty": "(suwung)",
"lineno": "Larik $1:",
"compareselectedversions": "Bandhingna vèrsi kapilih",
"showhideselectedversions": "Tampilaké/dhelikaké révisi kapilih",
- "editundo": "wurungaké",
+ "editundo": "wurung",
"diff-empty": "(Ora ana bedane)",
"diff-multi-sameuser": "({{PLURAL:$1|Saowahan madya|$1 owahan madya}} déning panganggo sing padha ora dituduhaké)",
"diff-multi-manyusers": "({{PLURAL:$1Siji rèvisi sedhengan|$1 rèvisi sedhengan}} déning luwih saka $2 {{PLURAL:$2|panganggo|panganggo}} ora dituduhaké)",
"searchmenu-exists": "'''Ana kaca kanthi jeneng \"[[$1]]\" ing wiki iki'''",
"searchmenu-new": "<strong>Gawéa kaca \"[[:$1]]\" nyang wiki iki!</strong> {{PLURAL:$2|0=|Uga delenga kaca sing katemu sarana panggolèking sampéyan.|Uga delenga kasiling panggolèk.}}",
"searchprofile-articles": "Kaca isi",
- "searchprofile-images": "Sarwamadya",
+ "searchprofile-images": "Multimédhia",
"searchprofile-everything": "Samubarang",
"searchprofile-advanced": "Lungidan",
"searchprofile-articles-tooltip": "Golèkan ing $1",
"yourvariant": "Werna basa isi:",
"prefs-help-variant": "Varian utawa ortograpi sing Sampéyan pilih kanggo nampilaké kaca kontèn saka wiki iki.",
"yournick": "Asma sesinglon/samaran (kagem tapak asta):",
- "prefs-help-signature": "Komentar ing kaca wicara kudu ditapak astani nganggo \"<nowiki>~~~~</nowiki>\" sing bakal dikonvèrsi dadi tapak asta panjenengan lan tanggal wektu.",
+ "prefs-help-signature": "Tanggapan ing kaca parembugan kudu ditandhatangani mawa \"<nowiki>~~~~</nowiki>\", sing bakal salin dadi tandha tangan lan cap wektumu.",
"badsig": "Tapak astanipun klèntu; cèk rambu HTML.",
"badsiglength": "Tapak asta panjenengan kedawan.\nAja luwih saka {{PLURAL:$1|karakter|karakter}}.",
"yourgender": "Kepiyé sampéyan medhar priangganing sampéyan?",
"grant-delete": "Busak kaca, owahan, lan isian cathetan",
"newuserlogpage": "Log naraguna anyar",
"newuserlogpagetext": "Ing ngisor iki kapacak log pandaftaran panganggo anyar.",
- "rightslog": "Log pangowahan hak aksès",
+ "rightslog": "Log hak panganggo",
"rightslogtext": "Ing ngisor iki kapacak log pangowahan marang hak-hak panganggo.",
"action-read": "maca kaca iki",
"action-edit": "besut kaca iki",
"action-createpage": "nggawé kaca-kaca",
- "action-createtalk": "gawé kaca wicara anyar",
+ "action-createtalk": "gawé kaca parembugan iki",
"action-createaccount": "gawé akun panganggo iki",
"action-minoredit": "tandhani iki minangka besutan cilik",
"action-move": "alihna kaca iki",
"statistics-header-hooks": "Statistik liya",
"statistics-articles": "Kaca-kaca isi",
"statistics-pages": "Gunggung kaca",
- "statistics-pages-desc": "Kabèh kaca ing wiki iki, klebu kaca wicara, pangalihan, lan liya-liyané.",
+ "statistics-pages-desc": "Kabèh kaca ing wiki iki, kalebu kaca parembugan, alihan, lsp.",
"statistics-files": "Berkas sing diunggahaké",
"statistics-edits": "Gunggung suntingan wiwit {{SITENAME}} diwiwiti",
"statistics-edits-average": "Rata-rata suntingan saben kaca",
"usercreated": "{{GENDER:$3|Digawé}} $1 wanci $2",
"newpages": "Kaca anyar",
"newpages-username": "Asma panganggo:",
- "ancientpages": "Kaca-kaca langkung sepuh",
+ "ancientpages": "Kaca paling lawas",
"move": "Pindhahen",
"movethispage": "Lih kaca iki",
"unusedimagestext": "Berkas-berkas sing kapacak iki ana nanging ora dienggo ing kaca apa waé.\nTulung digatèkaké yèn situs wèb liyané mbok-menawa bisa nyambung ing sawijining berkas sacara langsung mawa URL langsung, lan berkas-berkas kaya mengkéné iku mbok-menawa ana ing daftar iki senadyan ora dienggo aktif manèh.",
"categories": "Kategori",
"categoriespagetext": "{{PLURAL:$1|kategori ing ngisor iki ngandhut|kategori ing ngisor iki ngandhut}} kaca utawa media.\n[[Special:UnusedCategories|Kategori sing ora dianggo]] ora ditampilaké ing kéné.\nDeleng uga [[Special:WantedCategories|kategori sing diperlokaké]].",
"categoriesfrom": "Tampilaké kategori-kategori diwiwiti saka:",
- "deletedcontributions": "Sumbanganing panganggo sing dibusak",
+ "deletedcontributions": "Sumbangan panganggo sing dibusak",
"deletedcontributions-title": "Sumbanganing panganggo sing dibusak",
"sp-deletedcontributions-contribs": "sumbangan",
"linksearch": "Golèkan pranala njaba",
"delete-toobig": "Kaca iki ndarbèni sajarah panyuntingan sing dawa, yaiku ngluwihi $1 {{PLURAL:$1|revision|révisi}}.\nPambusakan kaca sing kaya mangkono mau wis ora diparengaké kanggo menggak anané karusakan ing {{SITENAME}}.",
"delete-warning-toobig": "Kaca iki duwé sajarah panyuntingan sing dawa, luwih saka $1 {{PLURAL:$1|révisi|révisi}}.\nMbusak kaca iki bisa ngrusak operasi basis data ing {{SITENAME}};\nkudu ngati-ati.",
"deleting-backlinks-warning": "'''Awas:''' Kaca liyane mungkin ana sing nautake ing kaca sing arep sampeyan busak.",
- "rollback": "Wurungaké besutan",
+ "rollback": "Pulihaké besutan",
"rollbacklink": "balèkaké",
"rollbacklinkcount": "balèkaké $1 {{PLURAL:$1|besutan|besutan}}",
"rollbacklinkcount-morethan": "balèkaké luwih saka $1 {{PLURAL:$1|suntingan|suntingan}}",
"rollbackfailed": "Pambalèkan gagal dilakoni",
"cantrollback": "Ora bisa mbalèkaké suntingan; panganggo pungkasan iku siji-sijiné penulis artikel iki.",
- "alreadyrolled": "Ora bisa mbalèkaké suntingan pungkasan [[:$1]] déning [[User:$2|$2]] ([[User talk:$2|Wicara]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); wong liya wis nyunting utawa mbalèkaké kaca artikel iku.\n\nSuntingan pungkasan dilakoni déning [[User:$3|$3]] ([[User talk:$3|Wicara]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+ "alreadyrolled": "Ora bisa mulihaké besutan pungkasan [[:$1]] déning [[User:$2|$2]] ([[User talk:$2|rembug]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); ana wong liya sing wis mbesut utawa mulihaké kaca iki.\n\nBesutan pungkasan kaca iku garapané [[User:$3|$3]] ([[User talk:$3|rembug]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "Ringkesan suntingan yaiku: <em>$1</em>.",
"revertpage": "Besutan sing dibalèkaké [[Special:Contributions/$2|$2]] ([[User talk:$2|rembugan]]) bab owahan pungkasan déning [[User:$1|$1]]",
"revertpage-nouser": "Suntingan déning panganggo sing didhelikake, dibalèkaké nèng benahan pungkasan déning [[User:$1|$1]]",
"tooltip-namespace_association": "Centhang kothak iki kanggo nglebokaké uga bilik jeneng gumenan utawa subyèk sing kakait karo bilik jeneng kapilih",
"blanknamespace": "(Pokok)",
"contributions": "Sumbangan {{GENDER:$1|panganggo}}",
- "contributions-title": "Sumbanganing panganggo $1",
+ "contributions-title": "Sumbangan panganggo $1",
"mycontris": "Sumbangan",
"anoncontribs": "Sumbangan",
"contribsub2": "Kanggo {{GENDER:$3|$1}} ($2)",
"sp-contributions-deleted": "sumbanganing panganggo sing dibusak",
"sp-contributions-uploads": "unggahan",
"sp-contributions-logs": "log",
- "sp-contributions-talk": "wicara",
+ "sp-contributions-talk": "rembug",
"sp-contributions-userrights": "pengaturan hak panganggo",
"sp-contributions-blocked-notice": "Panganggo iki lagi diblokir.\nÈntri log blokiran pungkasan sumadhiya nèng ngisor kanggo rujukan:",
"sp-contributions-blocked-notice-anon": "Alamat IP iki lagi diblokir.\nÈntri log blokiran pungkasan sumadhiya nèng ngisor kanggo rujukan:",
"sp-contributions-search": "Golèk sumbangan",
"sp-contributions-username": "Alamat IP utawa jeneng panganggo:",
- "sp-contributions-toponly": "Tuduhaké was suntingan saka benahan pungkasan",
+ "sp-contributions-toponly": "Tuduhaké besutan mligi rèvisi anyar",
+ "sp-contributions-newonly": "Tuduhaké besutan mligi kaca gawéan",
"sp-contributions-submit": "Golèk",
"whatlinkshere": "Sing nggayut mréné",
"whatlinkshere-title": "Kaca mawa pranala nggayut \"$1\"",
"tooltip-recreate": "Gawéa kaca iki manèh senadyan tau dibusak",
"tooltip-upload": "Miwiti pangunggahan",
"tooltip-rollback": "Balèkaké besutan-besutan kaca iki déning sing pungkasan nyumbang sarana saklikan.",
- "tooltip-undo": "\"Wurungaké\" mbalèkaké besutan iki lan mbukak blangko besutan sarana modhe pratuduh. Alesan kena diwuwuhaké ing babagan ringkesan.",
+ "tooltip-undo": "\"Wurung\" mbalèkaké besutan iki lan mbukak blangko besutan sarana modhe pratuduh. Alesan kena diwuwuhaké ing babagan ringkesan.",
"tooltip-preferences-save": "Simpen préperensi",
"tooltip-summary": "Isi tingkesan cendhak",
"anonymous": "{{PLURAL:$1|Panganggo|panganggo}} anon ing {{SITENAME}}.",
"logentry-newusers-create2": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1",
"logentry-newusers-byemail": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1 lan tembung sandhine dikirim lewat layang elektronik",
"logentry-newusers-autocreate": "Akun $1 {{GENDER:$2|digawé}} otomatis",
+ "logentry-protect-unprotect": "$1 {{GENDER:$2|ngilangi}} rereksan saka $3",
"logentry-rights-rights": "$1 {{GENDER:$2|ngganti}} golongané {{GENDER:$6|$3}} saka $4 dadi $5",
"logentry-rights-rights-legacy": "$1 {{GENDER:$2|ngganti}} golongané $3",
"logentry-rights-autopromote": "$1 otomatis {{GENDER:$2|dipromosikne}} saka $4 nèng $5",
"right-managechangetags": "[[Special:Tags|ტეგების]] შექმნა და (დე)აქტივაცია",
"right-applychangetags": "[[Special:Tags|tags]] მიღება თქვენ ცვლილებებთან ერთად",
"right-changetags": "თვითნებური [[Special:Tags|tags]] დამატება ან წაშლა ცალკეულ ცვლილებებსა და ჟურნალის ჩანაწერებში",
+ "right-deletechangetags": "მონაცემთა ბაზიდან [[Special:Tags|ტეგების]] წაშლა",
"grant-generic": "\"$1\" უფლებები",
"grant-group-page-interaction": "კავშირი გვერდებთან",
"grant-group-file-interaction": "კავშირი მედია-ფაილებთან",
"action-managechangetags": "ტეგების შექმნა და (დე)აქტივაცია",
"action-applychangetags": "ტეგების მიღება თქვენ ცვლილებებთან ერთად",
"action-changetags": "თავისუფალი ტეგების დამატება და წაშლა ცალკეულ ცვლილებებსა და ჟურნალების ჩანაწერებში",
+ "action-deletechangetags": "მონაცემთა ბაზიდან ტეგების წაშლა",
+ "action-purge": "ამ გვერდის წაშლა",
"nchanges": "$1 ცვლილება",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ბოლო ვიზიტის შემდეგ}}",
"enhancedrc-history": "ისტორია",
"upload-http-error": "მოხდა HTTP შეცდომა: $1",
"upload-copy-upload-invalid-domain": "ამ დომენში ატვირთვების კოპირება არ არის ხელმისაწვდომი.",
"upload-foreign-cant-upload": "ეს ვიკი არ არის დაკონფიგურირებული იმისათვის, რომ ატვირთოს ფაილების უცხო ფაილთა საწყობში.",
+ "upload-dialog-disabled": "ფაილის ატვირთვა ამ დიალოგური ფანჯრით გათიშულია ამ ვიკიზე.",
"upload-dialog-title": "ფაილის ატვირთვა",
"upload-dialog-button-cancel": "გაუქმება",
"upload-dialog-button-done": "შესრულდა",
"uploadstash-badtoken": "მითითებული მოქმედება ვერ შესრულდა. შესაძლოა, რედაქტირების უფლებამოსილების მოქმედების ვადა ამოიწურა. გთხოვთ, სცადეთ თავიდან.",
"uploadstash-errclear": "ფაილების გასუფთავება ვერ მოხერხდა.",
"uploadstash-refresh": "ფაილების სიის განახლება",
+ "uploadstash-thumbnail": "მინიატურის ნახვა",
"invalid-chunk-offset": "არასწორი საწყისი წერტილი",
"img-auth-accessdenied": "მოქმედება აკრძალულია",
"img-auth-nopathinfo": "დაკარგულია PATH_INFO.\nთქვენი სერვერი არ არის მომართული ამ ინფორმაციის გადასაცემად.\nშესაძლოა, ის მუშაობს CGI-ის ბაზაზე და არ გააჩნია img_auth მხარდაჭერა.\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization იხილეთ სურათის ავტორიზაცია.]",
"filerevert-submit": "გაუქმება",
"filerevert-success": "'''[[Media:$1|$1]]''' დაუბრუნდა ვერსიას [$4 $3, $2]-დან.",
"filerevert-badversion": "არ არსებობს ფაილის წინა ლოკალური ვერსია მოთხოვნილი თარიღითა და დროით",
+ "filerevert-identical": "ფაილის ამჟამინდელი ვერსია უკვე არის შერჩეულის იდენტური.",
"filedelete": "$1 წაშლა",
"filedelete-legend": "ფაილის წაშლა",
"filedelete-intro": "თქვენ შლით <strong>[[Media:$1|$1]]-ს</strong> მისი ისტორიით.",
"trackingcategories-msg": "კატეგორიის მიდევნება",
"trackingcategories-name": "შეტყობინების სახელი",
"trackingcategories-desc": "კატეგორიაში ჩართვის კრიტერიუმები",
+ "restricted-displaytitle-ignored": "გვერდები დაიგნორებული სათაურებით",
"noindex-category-desc": "გვერდი არ არის ინდექსირებული საძიებო სამუშაოებით, რადგან მასზე არის „ჯადოსნური სიტყვა“ <code><nowiki>__NOINDEX__</nowiki></code> და ის იმყოფება სახელთა სივრცეში, სადაც დასაშვებია ეს დროშა.",
"index-category-desc": "გვერდზე არის „ჯადოსნური სიტყვა“ <code><nowiki>__INDEX__</nowiki></code> (და გვერდი იმყოფება სახელთა სივრცეში, სადაც დაშვებულია ეს დროშა). ამიტომ იგი ინდექსირებულია საძიებო სამუშაოებით იმ შემთხვევებში, როცა ეს ჩვეულებრივ არ ხდება.",
"post-expand-template-inclusion-category-desc": "გვერდის ზომა უფრო გაიზრდება <code>$wgMaxArticleSize</code> ყველა თარგის ჩვენების შემდეგ, ამიტომ ზოგიერთი მათგანი არ იყო ნაჩვენები მთლიანად.",
"watchnologin": "რეგისტრაცია ვერ შესრულდა",
"addwatch": "კონტროლის სიაში დამატება",
"addedwatchtext": "„[[:$1]]“ და მისი განხილვის გვერდი დაემატა თქვენს [[Special:Watchlist|კონტროლის სიას]].",
+ "addedwatchtext-talk": "„[[:$1]]“ და მასთან დაკავშირებული გვერდი დაემატა თქვენს [[Special:Watchlist|კონტროლის სიას]].",
"addedwatchtext-short": "გვერდი „$1“ დაემატა თქვენი კონტროლის სიას.",
"removewatch": "კონტროლის სიიდან წაშლა",
"removedwatchtext": "„[[:$1]]“ და მისი განხილვის გვერდი ამოღებულია თქვენი [[Special:Watchlist|კონტროლის სიიდან]].",
+ "removedwatchtext-talk": "„[[:$1]]“ და მასთან დაკავშირებული გვერდი ამოღებულია თქვენი [[Special:Watchlist|კონტროლის სიიდან]].",
"removedwatchtext-short": "გვერდი „$1“ წაიშალა თქვენი კონტროლის სიიდან.",
"watch": "კონტროლი",
"watchthispage": "ამ გვერდის კონტროლი",
"rollbacklinkcount": "$1 {{PLURAL:$1|ცვლილების|ცვლილების}} გაუქმება",
"rollbacklinkcount-morethan": "$1-ზე მეტი {{PLURAL:$1|ცვლილების|ცვლილების}} გაუქმება",
"rollbackfailed": "შეცდომა გაუქმებისას",
+ "rollback-missingparam": "აკლია საჭირო პარამეტრები.",
"cantrollback": "შეუძლებელია უწინდელი რედაქციის აღდგენა; ის, ვინც უკანასკნელი ცვლილებები შეიტანა, ამ სტატიის ერთადერთი ავტორია.",
"alreadyrolled": "შეუძლებელია ბოლო ცვლილების გაუქმება [[:$1]], გაკეებული [[User:$2|$2]] ([[User talk:$2|განხილვა]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nვიღაცა სხვამ უკვე შეასწორა ან გაააუქმა ეს გვერდი.\n\nბოლო ცვლილებები შეიტანა [[User:$3|$3]] ([[User talk:$3|განხილვა]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "რედაქტირება განმარტებული იყო როგორც: <em>$1</em>.",
"changecontentmodel-success-text": "[[:$1]]-ის კონტენტის ტიპი შეიცვალა.",
"changecontentmodel-cannot-convert": "[[:$1]]-ის შინაარსის $2-ის ტიპზე კონვერტაცია შეუძლებელია.",
"changecontentmodel-nodirectediting": "$1 შინაარსის მოდელს არ აქვს პირდაპირი რედაქტირების მხარდაჭერა",
+ "changecontentmodel-emptymodels-title": "შინაარსის მოდელები არ არის ხელმისაწვდომი",
+ "changecontentmodel-emptymodels-text": "შინაარსი [[:$1]]-ზე არ კონვერტირდება არცერთ ტიპზე.",
"log-name-contentmodel": "შინაარსის მოდელის შეცვლის ჟურნალი",
"log-description-contentmodel": "გვერდის შინაარსის მოდელთან დაკავშირებული მოვლენები",
"logentry-contentmodel-new": "$1-მ {{GENDER:$2|შექმნა}} გვერდი $3, არა-სტანდარტული მოდელით \"$5\"",
"undeletehistorynoadmin": "ეს სტატია წაშლილია. წაშლის მიზეზი ნაჩვენებია მოკლე ანოტაციაში ქვემოთ, იმ მომხმარებელთა დეტალებთან ერთად ვინც რედაქტირება გაუკეთა ამ გვერდს წაშლის წინ. იმ წაშლილი ტექსტების აქტუალური ვერსიები მიღწევადია მხოლოდ ადმინისტრატორებისათვის.",
"undelete-revision": "$1-ის წაშლილი ვერსია ($5, $4-ის მდგომარეობით), შენახული მომხმარებლის $3 მიერ:",
"undeleterevision-missing": "არასწორი ან არარსებული ვერსია. სავარაუდოდ ქვენ გადახვედით არასწორ ბმულზე, ან იგი წაიშალა არქივიდან.",
+ "undeleterevision-duplicate-revid": "{{PLURAL:$1|ერთი ცვლილება|$1 ცვლილება}} ვერ აღდგა, რადგან {{PLURAL:$1|მისი|მათი}} <code>rev_id</code> უკვე გამოიყენებოდა.",
"undelete-nodiff": "წინა ცვლილება ვერ ვიპოვეთ.",
"undeletebtn": "აღდგენა",
"undeletelink": "ნახვა/აღდგენა",
"invalidateemail": "ელ-ფოსტის დადასტურების გაუქმება",
"notificationemail_subject_changed": "{{SITENAME}} რეგისტრირებული იმეილის მისამართები შეიცვალა",
"notificationemail_subject_removed": "{{SITENAME}} რეგისტრირებული იმეილის მისამართები წაიშალა",
+ "notificationemail_body_changed": "ვიღაცამ, სავარაუდოდ თქვენ, IP მისამართიდან $1,\n{{SITENAME}}ში შეცვალა „$2“ ანგარიშის იმეილის მისამართი „$3“-ზე.\n\nთუ ეს თქვენ არ იყავით, გთხოვთ დაუკავშირდით საიტის ადმინისტრატორს სასწრაფოდ.",
+ "notificationemail_body_removed": "ვიღაცამ, სავარაუდოდ თქვენ, IP მისამართიდან $1,\n{{SITENAME}}ში წაშალა ანგარიშის „$2“ იმეილის მისამართი.\n\nთუ ეს თქვენ არ იყავით, გთხოვთ დაუკავშირდით საიტის ადმინისტრატორს სასწრაფოდ.",
"scarytranscludedisabled": "[«Interwiki transcluding» გათიშულია]",
"scarytranscludefailed": "[$1-თან დაკავშირების შეცდომა]",
"scarytranscludefailed-httpstatus": "[ვერ მოხერხდა თარგის ჩატვირთვა $1-თვის: HTTP $2]",
"confirm-unwatch-button": "დიახ",
"confirm-unwatch-top": "მოვხსნა ეს გვერდი თქვენი კონტროლის სიიდან?",
"confirm-rollback-button": "კარგი",
+ "confirm-rollback-top": "დავაბრუნოთ რედაქტირებები ამ გვერდზე?",
"semicolon-separator": "; ",
"comma-separator": ", ",
"colon-separator": ": ",
"timezone-local": "ლოკალური",
"duplicate-defaultsort": "'''ყურადღება.'''სორტირების გასაღებს «$2»-ს გააჭრის წინა გასაღებს «$1»-ს.",
"duplicate-displaytitle": "<strong>ყურადღება:</strong> დისპლეის სათაური \"$2\" განსაზღვრავს ადრე გაცემულ დისპლეის სათაურს \"$1\".",
+ "restricted-displaytitle": "<strong>Warning:</strong> სათაური „$1“ იგნორირებულ იქნა, რადგან ის არ ემთხვევა გვერდის ნამდვილ სათაურს.",
"invalid-indicator-name": "<strong>შეცდომა:</strong> გვერდის სტატუსის ინდიკატორი <code>name</code> ატრიბუტი არ უნდა იყოს ცარიელი.",
"version": "ვერსია",
"version-extensions": "დაყენებული გაფართოებები",
"tags-delete-not-found": "აღნიშვნა „$1“ არ არსებობს.",
"tags-delete-too-many-uses": "ტეგი \"$1\" მიღებულია $2 ვერსიებთან, რაც იმას ნიშნავს, რომ იგი არ შეიძლება იყოს წაშლილი",
"tags-delete-warnings-after-delete": "ტეგი „$1“ წაიშალა, თუმცა აღმოჩენილია შემდეგი {{PLURAL:$2|შეტყობინება|შეტყობინებები}}:",
+ "tags-delete-no-permission": "თქვენ არ გაქვთ შეცვლილი ტეგების წაშლის უფლება.",
"tags-activate-title": "ტეგის გააქტიურება",
"tags-activate-question": "თქვენ ცდილობთ დასათაურების გააქტიურებას „$1“.",
"tags-activate-reason": "მიზეზი:",
"feedback-useragent": "მომხმარებლის აგენტი:",
"searchsuggest-search": "ძიება",
"searchsuggest-containing": "შეიცავს...",
+ "api-error-autoblocked": "თქვენი IP მისამართი ავტომატურად დაიბლოკა, რადგან ის გამოიყენა დაბლოკილმა მომხმარებელმა.",
"api-error-badaccess-groups": "თქვენ არ გაქვთ ამ ვიკიში ფაილების ატვირთვის უფლება.",
"api-error-badtoken": "შიდა შეცდომა: ცუდი ტოკენი.",
+ "api-error-blocked": "თქვენთვის რედაქტირება დაბლოკილია.",
"api-error-copyuploaddisabled": "ამ სერვერზე URL-მისამართის საშუალებით ატვირთვა გამორთულია.",
"api-error-duplicate": "საიტზე უკვე {{PLURAL:$1|არსებობს სხვა ფაილი|არსებობს სხვა ფაილები}} ანალოგიური შინაარსით.",
"api-error-duplicate-archive": "საიტზე ადრე {{PLURAL:$1|უკვე იყო ფაილი}} ანალოგიური შინაარსით, მაგრამ {{PLURAL:$1|ის წაიშალა|ისინი წაიშალა}}.",
"api-error-unknownerror": "უცნობი შეცდომა: „$1“.",
"api-error-uploaddisabled": "ატვირთვის მექანიზმი ამ ვიკიზე გამორთულია",
"api-error-verification-error": "ეს ფაილი ან რაიმე შეცდომას შეიცავს, ან არ აქვს სახელის გაფართოება.",
+ "api-error-was-deleted": "ფაილი ამ სახელწოდებით ადრე აიტვირთა და შემდეგ წაიშალა.",
"duration-seconds": "$1 {{PLURAL:$1|წამი|წამი}}",
"duration-minutes": "$1 {{PLURAL:$1|წუთი|წუთი}}",
"duration-hours": "$1 {{PLURAL:$1|საათი|საათი}}",
"sessionprovider-nocookies": "შესაძლოა ქუქები გათიშულია. გთხოვთ ჩართეთ და სცადეთ განმეორებით.",
"randomrootpage": "შემთხვევითი ძირეული გვერდი",
"log-action-filter-block": "ბლოკირების ტიპი:",
+ "log-action-filter-contentmodel": "შეინაარსის მოდელის მოდერაციის ტიპი:",
"log-action-filter-delete": "წაშლის ტიპი:",
"log-action-filter-import": "იმპორტის ტიპი:",
"log-action-filter-managetags": "ტეგის ცვლილების ტიპი:",
"log-action-filter-patrol": "შემოწმების ტიპი:",
"log-action-filter-protect": "დაცვის ტიპი:",
"log-action-filter-rights": "უფლების შეცვლის ტიპი:",
+ "log-action-filter-suppress": "დამალვის ტიპი:",
"log-action-filter-upload": "ატვირთვის ტიპი:",
"log-action-filter-all": "ყველა",
"log-action-filter-block-block": "დაბლოკვა",
"log-action-filter-block-reblock": "ბლოკირების შეცვლა",
"log-action-filter-block-unblock": "განბლოკვა",
+ "log-action-filter-contentmodel-change": "შინაარსის მოდელის შეცვლა",
+ "log-action-filter-contentmodel-new": "გვერდის შექმნა არასტანდარტული შინაარსის მოდელით",
+ "log-action-filter-delete-delete": "გვერდის წაშლა",
+ "log-action-filter-delete-restore": "გვერდის აღდგენა",
+ "log-action-filter-delete-event": "ჯურნალის ჩანაწერის წაშლა",
+ "log-action-filter-delete-revision": "ვერსიის წაშლა",
+ "log-action-filter-import-interwiki": "Transwiki-ს იმპორტი",
+ "log-action-filter-import-upload": "XML ატვირთვიდან იმპორტი",
+ "log-action-filter-managetags-create": "ტეგის შექმნა",
+ "log-action-filter-managetags-delete": "ტეგის წაშლა",
+ "log-action-filter-managetags-activate": "ტეგის აქტივაცია",
+ "log-action-filter-managetags-deactivate": "ტეგის დეაქტივაცია",
+ "log-action-filter-move-move": "გადატანა გადამისამართებების გადაწერის გარეშე",
+ "log-action-filter-move-move_redir": "გადატანა გადამისამართებების გადაწერით",
+ "log-action-filter-newusers-create": "შექმნა ანონიმური მომხმარებლის მიერ",
"log-action-filter-newusers-create2": "დარეგისტრირებული მომხმარებლის შექმნა",
"log-action-filter-newusers-autocreate": "ავტომატური შექმნა",
"log-action-filter-newusers-byemail": "პაროლით შექმნა, რომელიც გამოიგზავნა იმეილით",
+ "log-action-filter-patrol-patrol": "ხელით შემოწმება",
"log-action-filter-patrol-autopatrol": "ავტომატური შემოწმება",
"log-action-filter-protect-protect": "დაცვა",
+ "log-action-filter-protect-modify": "დაცვის შეცვლა",
"log-action-filter-protect-unprotect": "დაცვის მოხსნა",
"log-action-filter-protect-move_prot": "დაცვა გადატანისაგან",
+ "log-action-filter-rights-rights": "ხელით შეცვლა",
"log-action-filter-rights-autopromote": "ავტომატური შეცვლა",
+ "log-action-filter-suppress-event": "ჟურნალის დამალვა",
+ "log-action-filter-suppress-revision": "ცვლილების დამალვა",
+ "log-action-filter-suppress-delete": "გვერდის დამალვა",
+ "log-action-filter-suppress-block": "მომხმარებლის დამალვა ბლოკით",
+ "log-action-filter-suppress-reblock": "მომხმარებლის დამალვა ხელახლა ბლოკირებით",
"log-action-filter-upload-upload": "ახალი ატვირთვა",
"log-action-filter-upload-overwrite": "ხელახლა ატვირთვა",
+ "authmanager-authn-not-in-progress": "აუტენტიფიკაცია არ მიმდინარეობს ან სესიის მონაცემი დაიკარგა. გთხოვთ დაიწყეთ თავიდან.",
+ "authmanager-authn-no-primary": "მოწოდებული მონაცემები ვერ იქნა აუტენტიფიცირებული.",
+ "authmanager-authn-no-local-user": "მოწოდებული მონაცემები არ უკავშირდება არცერთ მომხმარებელს ამ ვიკიზე.",
+ "authmanager-create-disabled": "ანგარიშის შექმნა გათიშულია.",
+ "authmanager-create-from-login": "ანგარიშის შესაქმნელად, გთხოვთ შეავსეთ ქვემოთ მოცემული ველები.",
+ "authmanager-create-not-in-progress": "ანგარიშის შექმა არ მიმდინარეობს ან სესიის მონაცემი დაიკარგა. გთხოვთ დაიწყეთ თავიდან.",
+ "authmanager-create-no-primary": "მოწოდებული მონაცემები არ გამოდგა ანგარიშის შესაქმნელად.",
+ "authmanager-link-no-primary": "მოწოდებული მონაცემები არ გამოდგა ანგარიშის დასაკავშირებლად.",
+ "authmanager-link-not-in-progress": "ანგარიშის დაკავშირება არ მიმდინარეობს ან სესიის მონაცემი დაიკარგა. გთხოვთ დაიწყეთ თავიდან.",
"authmanager-authplugin-setpass-failed-title": "პაროლის ცვლილება ვერ განხორციელდა",
+ "authmanager-authplugin-setpass-failed-message": "აუთენთიფიკაციის პლაგინმა უარყო პაროლის ცვლილება.",
+ "authmanager-authplugin-create-fail": "აუთენთიფიკაციის პლაგინმა უარყო ანგარიშის შექმნა.",
+ "authmanager-authplugin-setpass-denied": "აუთენთიფიკაციის პლაგინი არ იძლევა პაროლების გამოცვლის უფლებას.",
+ "authmanager-authplugin-setpass-bad-domain": "არასწორი დომეინი.",
+ "authmanager-autocreate-noperm": "ავტომატური ანგარიშის შექმნა არ არის ნებადართული.",
+ "authmanager-autocreate-exception": "ავტომატური ანგარიშის შექმნა დროებით გათიშულია ადრინდელი ხარვეზების გამო.",
+ "authmanager-userdoesnotexist": "მომხმარებლის ანგარიში „$1“ არ არის რეგისტრირებული",
+ "authmanager-username-help": "მომხმარებლის სახელი აუთენთიფიკაციისთვის.",
+ "authmanager-password-help": "პაროლი აუთენთიფიკაციისთვის.",
+ "authmanager-domain-help": "დომეინი გარე აუთენთიფიკაციისთვის.",
+ "authmanager-retype-help": "დასადასტურებლად კვლავ შეიყვანეთ პაროლი.",
"authmanager-email-label": "ელ. ფოსტა",
"authmanager-email-help": "ელ. ფოსტის მისამართი",
"authmanager-realname-label": "ნამდვილი სახელი",
"authmanager-realname-help": "მომხმარებლის ნამდვილი სახელი",
+ "authmanager-provider-password": "პაროლზე დაფუძნებული აუთენთიფიკაცია",
+ "authmanager-provider-password-domain": "პაროლზე და დომეინზე დაფუძნებული აუთენთიფიკაცია",
+ "authmanager-provider-temporarypassword": "დროებითი პაროლი",
+ "authprovider-confirmlink-request-label": "ანგარიშები, რომლებიც დაკავშირებული უნდა იყოს",
+ "authprovider-confirmlink-success-line": "$1: დაუკავშირდა წარმატებით.",
+ "authprovider-confirmlink-failed": "ანგარიშის დაკავშირება არ შესრულდა სრულად: $1",
+ "authprovider-confirmlink-ok-help": "გააგრძელე დაკავშირების ჩავარდნის შეტყობინებების ჩვენების შემდეგ.",
"authprovider-resetpass-skip-label": "გამოტოვება",
"authprovider-resetpass-skip-help": "გამოტოვეთ პაროლის შეცვლის პროცესი.",
+ "authform-nosession-login": "ავტორიზაციამ წარმატებით ჩაიარა, თუმცა თქვენი ბრაუზერი ვერ ახერხებს მის „დამახსოვრებას“.\n\n$1",
+ "authform-nosession-signup": "ანგარიში შეიქმნა, თუმცა თქვენი ბრაუზერი ვერ ახერხებს მის „დამახსოვრებას“.\n\n$1",
+ "authform-newtoken": "არ არის ტოკენი. $1",
+ "authform-notoken": "არ არის ტოკენი",
+ "authform-wrongtoken": "არასწორი ტოკენი",
"specialpage-securitylevel-not-allowed-title": "არ არის ნებადართული",
- "credentialsform-account": "ანგარიშის სახელი:"
+ "specialpage-securitylevel-not-allowed": "უკაცრავად, თქვე არ შეგიძლიათ ამ გვერდის გამოყენება, რადგან თქვენი იდენთიფიკაცია არ არის დადასტურებული.",
+ "authpage-cannot-login": "შეუძლებელია ავტორიზაციის დაწყება.",
+ "authpage-cannot-login-continue": "შეუძლებელია ავტორიზაციის გაგრძელება. სავარაუდოდ, თქვენი სესიის დრო ამოიწურა.",
+ "authpage-cannot-create": "შეუძლებელია ანგარიშის შექმნის დაწყება.",
+ "authpage-cannot-create-continue": "შეუძლებელია ანგარიშის შექმნის გაგრძელება. სავარაუდოდ, თქვენი სესიის დრო ამოიწურა.",
+ "authpage-cannot-link": "შეუძლებელია ანგარიშის დაკავშირების დაწყება.",
+ "authpage-cannot-link-continue": "შეუძლებელია ანგარიშის დაკავშირების გაგრძელება. სავარაუდოდ, თქვენი სესიის დრო ამოიწურა.",
+ "cannotauth-not-allowed-title": "ნებართვა უარყოფილია",
+ "cannotauth-not-allowed": "თქვენ არ გაქვთ ამ გვერდის გამოყენების უფლება",
+ "changecredentials": "მონაცემების შეცვლა",
+ "changecredentials-submit": "მონაცემების შეცვლა",
+ "changecredentials-invalidsubpage": "$1 არ არის ვალიდური მონაცემის ტიპი.",
+ "changecredentials-success": "თქვენი მონაცემები შეიცვალა.",
+ "removecredentials": "მონაცემების წაშლა",
+ "removecredentials-submit": "მონაცემების წაშლა",
+ "removecredentials-invalidsubpage": "$1 არ არის ვალიდური მონაცემის ტიპი.",
+ "removecredentials-success": "თქვენი მონაცემები წაიშალა.",
+ "credentialsform-provider": "მონაცემის ტიპი:",
+ "credentialsform-account": "ანგარიშის სახელი:",
+ "cannotlink-no-provider-title": "არ არის დაკავშირებული ანგარიშები",
+ "cannotlink-no-provider": "არ არის დაკავშირებული ანგარიშები.",
+ "linkaccounts": "ანგარიშების დაკავშირება",
+ "linkaccounts-success-text": "ანგარიში დაკავშირებულია.",
+ "linkaccounts-submit": "ანგარიშების დაკავშირება",
+ "unlinkaccounts": "ანგარიშებისთვის დაკავშირების მოშორება",
+ "unlinkaccounts-success": "ანგარიშს მოეხსნა დაკავშირება.",
+ "userjsispublic": "შენიშვნა: ჯავასკრიპტის ქვეგვერდები არ უნდა შეიცავდეს პირადულ მონაცემებს, რადგან მას სხვა მომხმარებლებიც ხედავენ.",
+ "usercssispublic": "შენიშვნა: CSS ქვეგვერდები არ უნდა შეიცავდეს პირადულ მონაცემებს, რადგან მას სხვა მომხმარებლებიც ხედავენ."
}
"createacct-reason-ph": "Неге басқа тіркегі жасамақшысыз",
"createacct-submit": "Тіркелгіңізді жасаңыз",
"createacct-another-submit": "Тіркелгі жасау",
+ "createacct-continue-submit": "Тіркелуді жалғастыру",
"createacct-benefit-heading": "{{SITENAME}} сіздермен жасалады.",
"createacct-benefit-body1": "{{PLURAL:$1|өңдеме|өңдеме}}",
"createacct-benefit-body2": "{{PLURAL:$1|бет|бет}}",
"filerevert-submit": "되돌리기",
"filerevert-success": "'''[[Media:$1|$1]]''' 파일을 [$4 $2 $3 버전]으로 되돌렸습니다.",
"filerevert-badversion": "입력된 시간 기록을 가진 파일의 로컬 버전이 없습니다.",
+ "filerevert-identical": "파일의 현재 버전은 선택한 것과 이미 동일합니다.",
"filedelete": "$1 삭제하기",
"filedelete-legend": "파일 삭제하기",
"filedelete-intro": "'''[[Media:$1|$1]]''' 파일과 모든 역사를 삭제합니다.",
"minoredit": "Haec est recensio minor",
"watchthis": "Hanc paginam observare",
"savearticle": "Hanc redactionem servare",
+ "savechanges": "Mutationes divulgare",
"publishpage": "Hanc paginam divulgare",
"publishchanges": "Hanc recensionem divulgare",
"preview": "Praevidere",
"filerevert-submit": "Zrécksetzen",
"filerevert-success": "<strong>[[Media:$1|$1]]</strong> gouf op d'[$4 Versioun vum $2, $3 Auer] zréckgesat.",
"filerevert-badversion": "Et gëtt keng vireg lokal Versioun vun deem Fichier mat der Zäitinformatioun déi Dir uginn hutt.",
+ "filerevert-identical": "Déi aktuell Versioun vum Fichier ass identesch mat där erausgesichter.",
"filedelete": "Läsch \"$1\"",
"filedelete-legend": "Fichier läschen",
"filedelete-intro": "Dir läscht de Fichier '''[[Media:$1|$1]]''' mat all senge Versiounen (Historique).",
"specialpages-group-changes": "Rezent Ännerungen a Lëschten",
"specialpages-group-media": "Medie-Rapporten an eropgeluede Fichieren",
"specialpages-group-users": "Benotzer a Rechter",
- "specialpages-group-highuse": "Dacks benotzte Säiten",
+ "specialpages-group-highuse": "Dacks benotzt Säiten",
"specialpages-group-pages": "Lëschte vu Säiten",
"specialpages-group-pagetools": "Handwierksgeschir fir Säiten",
"specialpages-group-wiki": "Daten an Handwierksgeschir",
"subject-preview": "Anteprimma do soggetto:",
"previewerrortext": "Gh'è stæto un errô mentre se çercava de mostrâ l'anteprimma.",
"blockedtitle": "L'utente o l'é bloccòu",
- "blockedtext": "''''O to nomme utente ò adresso IP o l'è stæto bloccòu.'''\n\nO blòcco o l'è stæto fæto da $1. A raxon dæta a l'è ''$2''.\n\n* Iniçio do blocco: $8\n* Fin do blocco: $6\n* Utente blocou: $7\n\nL'è poscibbile contattâ $1 o un âtro [[{{MediaWiki:Grouppage-sysop}}|amministratô]] pe discûtte inscio blòcco.\nNo ti poeu doeuviâ o comando \"Manda un'e-mail a st'ûtente\" se no ti g'hæ 'n adresso e-mail registròu inte to [[Special:Preferences|preferençe]] e se no t'ê stæto bloccòu ascì.\nO to adresso IP o l'è $3, e o to blòcco ID o l'è #$5.\nPe piaxei, pe domandâ informaçioin, speçifficali tutti doî.",
+ "blockedtext": "''''O to nomme utente ò adresso IP o l'è stæto bloccòu.'''\n\nO blòcco o l'è stæto fæto da $1. A raxon dæta a l'è ''$2''.\n\n* Prinçippio do blocco: $8\n* Fin do blocco: $6\n* Utente blocou: $7\n\nL'è poscibbile contattâ $1 ò un atro [[{{MediaWiki:Grouppage-sysop}}|amministratô]] pe discûtte inscio blòcco.\nNo ti poeu doeuviâ o comando \"Manda un'e-mail a st'utente\" se no ti g'hæ 'n adreçço e-mail registròu inte to [[Special:Preferences|preferençe]] e se no t'ê stæto bloccòu ascì.\nO to adreçço IP o l'è $3, e o to blòcco ID o l'è #$5.\nPe piaxei, pe domandâ de informaçioin, speçifficali tutti doî.",
"autoblockedtext": "O teu addresso IP o l'è stæto bloccòu outomaticamente perché o l'ea za usòu da 'n âtro utente, bloccòu da $1.\nA raxon dæta a l'è stæta:\n\n:''$2''\n\n* Prinsippio do blòcco: $8\n* Fin do blòcco: $6\n\nTi peu contattâ $1 ò un âtro\n[[{{MediaWiki:Grouppage-sysop}}|amministratô]] pe discutte o blòcco.\n\nDanni a mente a che no ti pêu ûsâ o comando \"manda 'na e-mail a sto utente\" se non ti g'hæ 'n addresso de posta elettronega registròu in te têu [[Special:Preferences|preferense]] e se ti no t'ê stæto bloccòu ascì.\n\nO to adresso IP o l'è $3, e o to blòcco ID o l'è #$5. Pe piaxei, pe domandâ informaçioin, speçifficali tutti doî.",
"blockednoreason": "nisciun-a motivaçion dæta",
"whitelistedittext": "Pe modificâ e paggine l'è necessaio $1.",
"defemailsubject": "Messaggio da {{SITENAME}} da l'utente \"$1\"",
"usermaildisabled": "e-mail utente disabilitâ",
"usermaildisabledtext": "No l'è poscibbile inviâ de e-mail a di atri utenti insce questo wiki",
- "noemailtitle": "Nisciun adreççoo e-mail",
+ "noemailtitle": "Nisciun adreçço e-mail",
"noemailtext": "Questo utente o no l'ha indicou un adreçço e-mail vallido.",
"nowikiemailtext": "Questo utente o l'ha scerto de no riçeive messaggi de posta elettronica da-i atri utenti.",
"emailnotarget": "Nomme utente do destinataio inexistente o non vallido.",
"emailto": "A:",
"emailsubject": "Sogetto:",
"emailmessage": "Messaggio:",
- "emailsend": "Spèdi",
- "emailccme": "Mandame unn-a copia do messagio co unn-a lettìa elettronega.",
+ "emailsend": "Spedisci",
+ "emailccme": "Mandime una copia do messaggio a-o mæ adreçço.",
"emailccsubject": "Coppia do messaggio inviou a $1: $2",
"emailsent": "E-mail spedïa",
"emailsenttext": "A teu e-mail a l'è stæta spedïa.",
"export-templates": "Inciodi i template",
"export-pagelinks": "Includdi paggine colegæ scin a 'na profonditæ de:",
"export-manual": "Azonzi paggine manoalmente:",
- "allmessages": "Messaggi do scistemma",
+ "allmessages": "Messaggi do scistema",
"allmessagesname": "Nomme",
"allmessagesdefault": "Testo predefinio",
"allmessagescurrent": "Testo corrente",
"backend-fail-connect": "Не можев да се поврзам со складишната основа „$1“.",
"backend-fail-internal": "Се појави непозната грешка во складишната основа „$1“.",
"backend-fail-contenttype": "Не можев да утврдам каква содржина има податотеката што треба да ја складирам во „$1“.",
- "backend-fail-batchsize": "Складишната основа доби блок од $1 податочна {{PLURAL:$1|операција|операции}}, а ограничувањето е $2 {{PLURAL:$2|операција|операции}}.",
+ "backend-fail-batchsize": "Складишната основа доби блок од $1 {{PLURAL:$1|податотечна постапка|податотечни постапки}}, а ограничувањето е $2 {{PLURAL:$2|постапка|постапки}}.",
"backend-fail-usable": "Не можев да ја прочитам или запишам податотеката „$1“ бидејќи немате доволно дозволи или поради тоа што недостасуваат именици/содржатели.",
"filejournal-fail-dbconnect": "Не можев да се поврзам со дневничката база за складишната основа „$1“.",
"filejournal-fail-dbquery": "Не можев да ја подновам дневничката база за складишната основа „$1“.",
"filerevert-submit": "Врати",
"filerevert-success": "'''[[Media:$1|$1]]''' е вратен на [$4 верзијата од $3, $2].",
"filerevert-badversion": "Нема претходна месна верзија на оваа податотека со даденото време.",
+ "filerevert-identical": "Тековната верзија на податотеката е веќе истоветна на избраната.",
"filedelete": "Избриши го $1",
"filedelete-legend": "Избриши податотека",
"filedelete-intro": "Ја бришете податотеката '''[[Media:$1|$1]]''' заедно со нејзината историја.",
"unit-pixel": "п",
"confirm_purge_button": "OK",
"confirm-purge-top": "Да го исчистам меѓускладот на страницава?",
- "confirm-purge-bottom": "Со оваа опеÑ\80аÑ\86иÑ\98а се чисти опслужувачкиот меѓусклад и се прикажува најновата верзија.",
+ "confirm-purge-bottom": "Со оваа поÑ\81Ñ\82апка се чисти опслужувачкиот меѓусклад и се прикажува најновата верзија.",
"confirm-watch-button": "ОК",
"confirm-watch-top": "Да ја додадам страницава во набљудуваните?",
"confirm-unwatch-button": "ОК",
"filerevert-submit": "पूर्वपदास न्या",
"filerevert-success": "[$3, $2 प्रमाणे आवर्तन $4]कडे<strong>[[Media:$1|$1]]</strong>उलटवण्यात आली.",
"filerevert-badversion": "दिलेलेल्या वेळ मापनानुसार,या संचिकेकरिता कोणतीही पूर्वीची स्थानिक आवृत्ती नाही.",
+ "filerevert-identical": "या संचिकेची सध्याची आवृत्ती ही निवड केलेल्या आवृत्तीसमच आहे.",
"filedelete": "$1 वगळा",
"filedelete-legend": "संचिका वगळा",
"filedelete-intro": "तुम्ही<strong>[[Media:$1|$1]]</strong>त्याच्या सर्व इतिहासासह,वगळण्याच्या तयारीत आहात.",
"minoredit": "အရေးမကြီးသော ပြင်ဆင်မှု ဖြစ်သည်",
"watchthis": "ဤစာမျက်နှာကို စောင့်ကြည့်ရန်",
"savearticle": "ဤစာမျက်နှာကို သိမ်းရန်",
+ "savechanges": "ပြောင်းလဲမှုများကို သိမ်းရန်",
"publishpage": "စာမျက်နှာကို လွှင့်တင်ရန်",
"publishchanges": "ပြောင်းလဲမှုများကို လွှင့်တင်ရန်",
"preview": "နမူနာ",
"savearticle": "Lagre siden",
"savechanges": "Lagre endringer",
"publishpage": "Publiser siden",
- "publishchanges": "Publiser endringene",
+ "publishchanges": "Publiser endringer",
"preview": "Forhåndsvisning",
"showpreview": "Forhåndsvisning",
"showdiff": "Vis endringer",
"faqpage": "Project:धैरै सोधिएका प्रश्नहरु",
"actions": "कार्यहरु",
"namespaces": "नेमस्पेस",
- "variants": "बहà¥\81रà¥\81पहरà¥\81",
+ "variants": "बहà¥\81रà¥\81पहरà¥\82",
"navigation-heading": "नेविगेशन मेनू",
"errorpagetitle": "त्रुटि",
"returnto": "$1 मा फर्कनुहोस् ।",
"image_tip": "इम्बेडेड(जडान गरिएको) फाइल",
"media_sample": "उदाहरण.ogg",
"media_tip": "फाइल लिङ्क",
- "sig_tip": "तपाà¤\88à¤\81को समयछाप सहितको दस्तखत",
+ "sig_tip": "तपाà¤\88à¤\82को समयछाप सहितको दस्तखत",
"hr_tip": "क्षितिजिय रेखा (कम प्रयोग गर्नुहोस्)",
"summary": "सारांश:",
"subject": "विषय/शीर्षक:",
"showpreview": "पूर्वालोकन देखाउनुहोस्",
"showdiff": "परिवर्तन देखाउनुहोस्",
"blankarticle": "<strong>चेतावनी:</strong> तपाईं एउटा खालि पृष्ठको निर्माण गर्दै हुनुहुन्छ।\nयदि तपाईं \"{{int:savearticle}}\" लाई पुनः थिच्नुहुन्छ भने पृष्ठ बिना कुनै सामग्री नै निर्मित गरिनेछ।",
- "anoneditwarning": "<strong>à¤\9aà¥\87तावनà¥\80:</strong> तपाà¤\88à¤\81लà¥\87 पà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81 à¤à¤\8fà¤\95à¥\8b à¤\9bà¥\88न । तपाà¤\88à¤\81à¤\95à¥\8b à¤\86à¤\87पि ठà¥\87à¤\97ाना पà¥\83षà¥\8dठसमà¥\8dपादन à¤\87तिहासमा दरà¥\8dता à¤\97रिनà¥\87 à¤\9b र यà¥\8b सबà¥\88लà¥\87 हà¥\87रà¥\8dन सà¤\95à¥\8dà¤\9bन । यदि तपाà¤\88à¤\82 <strong>[$1 लà¤\97à¤\88न]</strong> वा <strong>[$2 नयाà¤\81 à¤\96ाता बनाà¤\89नà¥\87] à¤\97रà¥\8dनà¥\81à¤à¤¯à¥\8b à¤à¤¨à¥\87 तपाà¤\88à¤\82दà¥\8dवारा à¤\97रिà¤\8fà¤\95à¥\8b समà¥\8dपादन तपाà¤\88à¤\82à¤\95à¥\8b पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतानाममा à¤\9cà¥\8bडिनà¥\87à¤\9b।",
+ "anoneditwarning": "<strong>à¤\9aà¥\87तावनà¥\80:</strong> तपाà¤\88à¤\82लà¥\87 पà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81 à¤à¤\8fà¤\95à¥\8b à¤\9bà¥\88न । तपाà¤\88à¤\82à¤\95à¥\8b à¤\86à¤\87पि ठà¥\87à¤\97ाना पà¥\83षà¥\8dठसमà¥\8dपादन à¤\87तिहासमा दरà¥\8dता à¤\97रिनà¥\87 à¤\9b र यà¥\8b सबà¥\88लà¥\87 हà¥\87रà¥\8dन सà¤\95à¥\8dà¤\9bनà¥\8d । यदि तपाà¤\88à¤\82 <strong>[$1 लà¤\97à¤\88न]</strong> वा <strong>[$2 नयाà¤\81 à¤\96ाता बनाà¤\89नà¥\87] à¤\97रà¥\8dनà¥\81à¤à¤¯à¥\8b à¤à¤¨à¥\87 तपाà¤\88à¤\82दà¥\8dवारा à¤\97रिà¤\8fà¤\95à¥\8b समà¥\8dपादन तपाà¤\88à¤\82à¤\95à¥\8b पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतानाममा à¤\9cà¥\8bडिनà¥\87à¤\9b ।",
"anonpreviewwarning": "''तपाईंले प्रवेश गर्नु भएको छैन। संग्रह (Save) गरेको खण्डमा पृष्ठको इतिहासमा तपाईंको IP ठेगाना अंकित गरिनेछ।''",
"missingsummary": "'''यादगर्नुहोस् :''' तपाईंले सम्पादन सारांश दिनुभएको छैन ।\nयदि तपाईंले \"{{int:savearticle}}\" थिच्नुभयो भने , सारांश बिना नै संग्रहित गरिने छ ।",
"selfredirect": "<strong>चेतावनी:</strong> तपाईं यस पृष्ठलाई आफुमा पुनः निर्देशित गर्दै हुनुहुन्छ।\nहुनसक्छ तपाईं अनुप्रेषितको लागि गलत लक्ष्य निर्दिष्ट गर्दै हुनुहुन्छ, वा गलत पृष्ठको सम्पादन गर्दै हुनुहुन्छ।\nतपाईं पुनः एकपटक \"{{int:savearticle}}\" क्लिक गर्नुहुन्छ, पुनः निर्देशित त्यसै पनि बनाइनेछ।",
"diff-multi-manyusers": "($2 {{PLURAL:$2|भन्दा अधिक प्रयोगकर्ता|भन्दा अधिक प्रयोगकर्ताहरू}}द्वारा {{PLURAL:$1|एउटा मध्यवर्ती संशोधन|$1 मध्यवर्ती संशोधनहरू}} नदेखाइएको)",
"difference-missing-revision": "यस अन्तर {{PLURAL:$2|को एक अवतरण|को $2 अवतरण}} ($1) {{PLURAL:$2|भेटिएन|खोज्न सकिएन}}।\n\nयो सामान्य रूपमा एउटा हताइएको पृष्ठको अवतरणहरूमा अन्तर खोज्दा हुन्छ । अधिक जानकारी [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाइएको लग]मा हेर्न सकिन्छ।",
"searchresults": "खोज नतिजाहरू",
- "searchresults-title": " \"$1\"à¤\95à¥\8b लाà¤\97ि à¤\96à¥\8bà¤\9c नतिà¤\9cाहरà¥\81",
+ "searchresults-title": " \"$1\"à¤\95à¥\8b लाà¤\97ि à¤\96à¥\8bà¤\9c नतिà¤\9cाहरà¥\82",
"titlematches": "पृष्ठ शिर्षक मिल्छ",
"textmatches": "पृष्ठ पाठ मिल्छ",
"notextmatches": "अक्षरस् पेज भेटिएन",
"next-page": "अर्को पृष्ठ",
"prevn-title": "पहिलेको $1 {{PLURAL:$1|नतिजा|नतिजाहरु}}",
"nextn-title": "यस पछिको $1 {{PLURAL:$1|नतिजा |नतिजाहरु}}",
- "shown-title": "दà¥\87à¤\96ाà¤\89नà¥\87 $1 {{PLURAL:$1|नतिà¤\9cा|नतिà¤\9cाहरà¥\81}} प्रति पृष्ठ",
+ "shown-title": "दà¥\87à¤\96ाà¤\89नà¥\87 $1 {{PLURAL:$1|नतिà¤\9cा|नतिà¤\9cाहरà¥\82}} प्रति पृष्ठ",
"viewprevnext": "हेर्नुहोस् ($1 {{int:pipe-separator}} $2) ($3)",
"searchmenu-exists": "''' \"[[:$1]]\" नाम गरेको पृष्ठ यो विकीमा रहेको छ'''",
"searchmenu-new": "<strong>\"[[:$1]]\" पृष्ठ यस विकिमा बनाउनुहोस्!</strong> {{PLURAL:$2|0=|तपाईंले खोज गरी भटिएको पृष्ठ पनि मिलान गर्नुहोस्।|तपाईंको खोज परिणाम पनि हेर्नुहोस।}}",
"showingresults": "देखाउँदै {{PLURAL:$1|'''१''' नतिजा|'''$1''' नतिजाहरू }} , #'''$2''' बाट सुरुहुने ।",
"showingresultsinrange": "देखाई रहेको छ{{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> परिणाम}} सम्म पहुँच #<strong>$2</strong> देखि #<strong>$3</strong> मा।",
"search-showingresults": "{{PLURAL:$4|<strong>$3</strong> मा बाट <strong>$1</strong> परिणाम|<strong>$3</strong> मा बाट परिणाम <strong>$1 - $2</strong>}}",
- "search-nonefound": "तपाà¤\88à¤\81को क्वेरीसँग मेल खाने नतिजाहरू भेटिएनन्",
+ "search-nonefound": "तपाà¤\88à¤\82को क्वेरीसँग मेल खाने नतिजाहरू भेटिएनन्",
"powersearch-legend": "उन्नत खोज",
"powersearch-ns": "नेमस्पेसेजहरूमा खोज्ने :",
"powersearch-togglelabel": "जाँच्ने :",
"recentchangeslinked-feed": "सम्बन्धित परिवर्तनहरू",
"recentchangeslinked-toolbox": "सम्बन्धित परिवर्तनहरू",
"recentchangeslinked-title": "\"$1\" सँग सम्बन्धित परिवर्तन",
- "recentchangeslinked-summary": "यो सूची निर्दिष्ट पृष्ठ (वा निर्दिष्ट श्रेणी)सित जोडिएका भर्खरै परिवर्तन भएका पृष्ठको हो। [[Special:Watchlist|तपाईँको निगरानी सूची]]का पृष्ठहरू <strong>गाढा अक्षरमा</strong> छन्।",
+ "recentchangeslinked-summary": "यो सूची निर्दिष्ट पृष्ठ (वा निर्दिष्ट श्रेणी)सित जोडिएका भर्खरै परिवर्तन भएका पृष्ठको हो । [[Special:Watchlist|तपाईंको निगरानी सूची]]का पृष्ठहरू <strong>गाढा अक्षरमा</strong> छन् ।",
"recentchangeslinked-page": "पृष्ठ नाम:",
"recentchangeslinked-to": "यसको सट्टा यो पृष्ठसँग जोडिएका पृष्ठहरूको परिवर्तन देखाउने",
"upload": "फाइल उर्ध्वभरण",
"filehist-dimensions": "आकारहरू",
"filehist-filesize": "फाइल आकार",
"filehist-comment": "टिप्पणी",
- "imagelinks": "फाà¤\87लà¤\95à¥\8b पà¥\8dरयà¥\8bà¤\97हरà¥\81",
+ "imagelinks": "फाà¤\87लà¤\95à¥\8b पà¥\8dरयà¥\8bà¤\97हरà¥\82",
"linkstoimage": "यस फाइलमा निम्न{{PLURAL:$1|पृष्ठ जोडिन्छ|$1 पृष्ठहरू जोडिन्छन्}}:",
"linkstoimage-more": "$1 भन्दा अधिक {{PLURAL:$1|पृष्ठ लिङ्क|पृष्ठ लिङ्कहरू}} यस फाइलसँग जोडिएको छ। \nनिम्नलिखित सूची फाइलसँग {{PLURAL:$1|पहिलो पृष्ठ लिङ्क|पहिलो $1 पृष्ठ लिङ्कहरू}} जोडिने देखाउँछ।\n[[Special:WhatLinksHere/$2|पूर्ण सूची]] पनि उपलब्ध छ।",
"nolinkstoimage": "यो फाईलसंग लिंकभएको कुनै पृष्ठ छैन.",
"duplicatesoffile": "निम्नलिखित {{PLURAL:$1|फाइलको प्रतिलिपि हो|$1 फाइलहरूको प्रतिलिपि हो}} ([[Special:FileDuplicateSearch/$2|अधिक जानकारीहरू]]):",
"sharedupload": "यो फाइल $1 को हो र अन्य परियोजनामा प्रयोग गरिएको हुनसक्छ।",
"sharedupload-desc-there": "यो फाइल $1 बाट हो र अन्य परियोजनाहरू द्वारा पनि प्रयोग गर्न सकिनेछ। अधिक जानकारीको लागि कृपया [$2 फाइल विवरण पृष्ठ] हेर्नुहोस।",
- "sharedupload-desc-here": "यà¥\8b फाà¤\87ल $1 बाà¤\9f हà¥\8b र à¤\85नà¥\8dय परियà¥\8bà¤\9cनाहरà¥\82 दà¥\8dवारा पनि पà¥\8dरयà¥\8bà¤\97 à¤\97रà¥\8dन सà¤\95िनà¥\8dà¤\9b। \nतà¥\8dयहाà¤\81 नà¥\87र यसà¤\95à¥\8b [$2 फ़ाà¤\87ल विवरण पà¥\83षà¥\8dठ]मा रहà¥\87à¤\95à¥\8b विवरण तल दिà¤\87à¤\8fà¤\95à¥\8b à¤\9b।",
+ "sharedupload-desc-here": "यो फाइल $1 बाट हो र अन्य परियोजनाहरू द्वारा पनि प्रयोग गर्न सकिन्छ। \nत्यहाँ नेर यसको [$2 फाइल विवरण पृष्ठ]मा रहेको विवरण तल दिइएको छ।",
"sharedupload-desc-edit": "यो फाइल $1 बाट हो र अन्य परियोजनाहरू द्वारा पनि प्रयोग गर्न सकिन्छ। \nशायद तपाईं [$2 त्यहाँ यसको फाइल विवरण पृष्ठ]लाई सम्पादित गर्न चाहनुहुन्छ।",
"sharedupload-desc-create": "यो फाइल $1 बाट हो र अन्य परियोजनाहरू द्वारा पनि प्रयोग गर्न सकिन्छ। \nशायद तपाईं [$2 त्यहाँ यसको फाइल विवरण पृष्ठ]लाई सम्पादित गर्न चाहनुहुन्छ।",
"filepage-nofile": "यस नामको फाइल छैन।",
"shared-repo-from": " $1 बाट",
"shared-repo": "एल साझा भण्डार",
"shared-repo-name-wikimediacommons": "विकिमीडिया कमन्स",
- "upload-disallowed-here": "तपाà¤\88à¤\81ले यो फाइल अधिलेखन गर्न सक्नुहुन्न ।",
+ "upload-disallowed-here": "तपाà¤\88à¤\82ले यो फाइल अधिलेखन गर्न सक्नुहुन्न ।",
"filerevert": "पूर्वस्थिति $1 मा फर्काउने",
"filerevert-legend": " फाइल पूर्वस्थितीमा फर्काउने",
"filerevert-intro": "तपाईं <strong>[[Media:$1|$1]]</strong>लाई [$4 $2 मा $3 बजेको अवतरण] लाई पूर्ववत गर्दै हुनुहुन्छ।",
"javascripttest": "JavaScript जाँच गरिदै",
"javascripttest-pagetext-unknownaction": "अज्ञात कारवाही \"$1\" ।",
"javascripttest-qunit-intro": "mediawiki.org मा [$1 जाँचको कागजात] हेर्नुहोस् ।",
- "tooltip-pt-userpage": "तपाईंको प्रयोगकर्ता पृष्ठ",
+ "tooltip-pt-userpage": "{{GENDER:| तपाईंको प्रयोगकर्ता}} पृष्ठ",
"tooltip-pt-anonuserpage": "तपाईँ जुन IP ठेगानाको रुपमा सम्पादन गर्दै हुनुहुन्छ , त्यसको प्रयोगकर्ता पृष्ठ निम्न छ :",
- "tooltip-pt-mytalk": "तपाईंको वार्ता पृष्ठ",
+ "tooltip-pt-mytalk": "{{GENDER:|तपाईंको}} वार्ता पृष्ठ",
"tooltip-pt-anontalk": "यो IP ठेगानाबाट गरिएका सम्पादनका बारेमा बार्तालाप",
- "tooltip-pt-preferences": "तपाईंका अभिरुचिहरू",
+ "tooltip-pt-preferences": "{{GENDER:|तपाईंका}} अभिरुचिहरू",
"tooltip-pt-watchlist": "पृष्ठहरूको सूची जसका परिवर्तनहरूलाई तपाईँले निगरानी गरिरहनु भएको छ",
- "tooltip-pt-mycontris": "तपाईंका योगदानहरूको सूची",
- "tooltip-pt-login": "तपाà¤\88à¤\81लाà¤\88 पà¥\8dरवà¥\87शगर्न सुझाव दिइन्छ ; तर यो जरुरी भने छैन",
+ "tooltip-pt-mycontris": "{{GENDER:|तपाईंका}} योगदानहरूको सूची",
+ "tooltip-pt-login": "तपाà¤\88à¤\82लाà¤\88 पà¥\8dरवà¥\87स गर्न सुझाव दिइन्छ ; तर यो जरुरी भने छैन",
"tooltip-pt-logout": "निर्गमन (लग आउट) गर्नुहोस्",
- "tooltip-pt-createaccount": "तपाईंलाई खाता बनाउन र लग इन गर्न हामि प्रोत्साहित गर्छौ; तथापि, यो अनिवार्य भने छैन।",
+ "tooltip-pt-createaccount": "तपाईंलाई खाता बनाउन र लग इन गर्न हामि प्रोत्साहित गर्छौ; तथापि, यो अनिवार्य भने छैन ।",
"tooltip-ca-talk": "सामग्री पृष्ठबारेमा छलफल",
"tooltip-ca-edit": "यो पृष्ठ सम्पादन गर्ने",
"tooltip-ca-addsection": "नयाँ खण्ड सुरु गर्नुहोस्",
"tooltip-ca-viewsource": "यो पृष्ठ सुरक्षित गरिएको छ। यसको श्रोत हेर्न सक्नुहुन्छ।",
- "tooltip-ca-history": "यस पà¥\83षà¥\8dठà¤\95à¥\8b पहिलà¥\87à¤\95ा पà¥\81नरावलà¥\8bà¤\95नहरà¥\81",
+ "tooltip-ca-history": "यस पà¥\83षà¥\8dठा पहिलà¥\87à¤\95ा पà¥\81नरावलà¥\8bà¤\95नहरà¥\82",
"tooltip-ca-protect": "यो पृष्ठलाई संरक्षित गर्नुहोस्",
"tooltip-ca-unprotect": "यस पृष्ठको सुरक्षा परिवर्तन गर्ने",
"tooltip-ca-delete": "यो पृष्ठ मेटाउनुहोस्",
"tooltip-ca-undelete": "मेटिएको भए पनि यो पृष्ठको सम्पादनहरू पुन:प्राप्त गर्नुहोस्",
"tooltip-ca-move": "यो पृष्ठलाई सार्नुहोस्",
- "tooltip-ca-watch": "यà¥\8b पà¥\83षà¥\8dठलाà¤\88 तपाà¤\88à¤\81को अवलोकनसूचीमा थप्नुहोस्",
+ "tooltip-ca-watch": "यà¥\8b पà¥\83षà¥\8dठलाà¤\88 तपाà¤\88à¤\82को अवलोकनसूचीमा थप्नुहोस्",
"tooltip-ca-unwatch": "यो पृष्ठलाई तपाईँको अवलोकनसूचीबाट हटाउनुहोस्",
"tooltip-search": "{{SITENAME}} मा खोज्नुहोस्",
"tooltip-search-go": "यदि यो नामको पृष्ठ रहेको छ भने त्यसमा जाने",
"tooltip-search-fulltext": "यो पाठको लागि पृष्ठहरू खोज्नुहोस्",
"tooltip-p-logo": "मुख्य पृष्ठ",
"tooltip-n-mainpage": "मुख्य पृष्ठमा जाने",
- "tooltip-n-mainpage-description": "मà¥\81à¤\96à¥\8dय पà¥\83षà¥\8dठमा à¤\9cानà¥\81हà¥\8bà¥\8dसà¥\8d",
- "tooltip-n-portal": "à¤\86यà¥\8bà¤\9cनाà¤\95ा बारà¥\87मा, तपाà¤\88à¤\81 के गर्न सक्नुहुन्छ, सामग्री कहाँ भेट्टाउने",
+ "tooltip-n-mainpage-description": "मुख्य पृष्ठमा जानुहोस्",
+ "tooltip-n-portal": "à¤\86यà¥\8bà¤\9cनाà¤\95ा बारà¥\87मा, तपाà¤\88à¤\82 के गर्न सक्नुहुन्छ, सामग्री कहाँ भेट्टाउने",
"tooltip-n-currentevents": "हालैको घटनाको बारेमा पृष्ठभूमि जानकारी पत्ता लगाउनुहोस्",
- "tooltip-n-recentchanges": "विà¤\95िमा à¤\97रिà¤\8fà¤\95ा हालà¥\88à¤\95ा परिवरà¥\8dतनहरà¥\81को सूची",
- "tooltip-n-randompage": "à¤\9cà¥\81न à¤\95à¥\81नà¥\88 पृष्ठ खोल्ने",
+ "tooltip-n-recentchanges": "विà¤\95िमा à¤\97रिà¤\8fà¤\95ा हालà¥\88à¤\95ा परिवरà¥\8dतनहरà¥\82को सूची",
+ "tooltip-n-randompage": "à¤\95à¥\81नà¥\88 à¤\8fà¤\95 पृष्ठ खोल्ने",
"tooltip-n-help": "पत्तालगाउनु पर्ने स्थान",
"tooltip-t-whatlinkshere": "यो सँग जोडिएका सबै विकि पृष्ठहरूको सूची",
"tooltip-t-recentchangeslinked": "यस पृष्ठमा जोडिएका पृष्ठहरूमा हालैको परिवर्तन",
"tooltip-ca-nstab-help": "सहायता पृष्ठ हेर्नुहोस्",
"tooltip-ca-nstab-category": "श्रेणी पृष्ठ हेर्ने",
"tooltip-minoredit": "यसलाई सामान्य सम्पादनको रुपमा चिनो लगाउने",
- "tooltip-save": "तपाà¤\88à¤\81लà¥\87 à¤\97रà¥\87à¤\95ा परिवरà¥\8dतनहरà¥\82 सà¤\82ग्रह गर्नुहोस्",
- "tooltip-preview": "तपाà¤\88à¤\81à¤\95à¥\8b परिवरà¥\8dतनà¤\95à¥\8b पà¥\82रà¥\8dवरà¥\82प , à¤\95à¥\83पया सà¤\82ग्रह गर्नु अघि यो प्रयोग गर्नुहोला !",
- "tooltip-diff": "तपाà¤\88à¤\81ले पाठमा के के परिवर्तन गर्नुभयो भनेर देखाउने",
+ "tooltip-save": "तपाà¤\88à¤\82à¤\95ा परिवरà¥\8dतनहरà¥\82 सà¤\99à¥\8dग्रह गर्नुहोस्",
+ "tooltip-preview": "तपाà¤\88à¤\82à¤\95à¥\8b परिवरà¥\8dतनà¤\95à¥\8b पà¥\82रà¥\8dवरà¥\82प , à¤\95à¥\83पया सà¤\99à¥\8dग्रह गर्नु अघि यो प्रयोग गर्नुहोला !",
+ "tooltip-diff": "तपाà¤\88à¤\82ले पाठमा के के परिवर्तन गर्नुभयो भनेर देखाउने",
"tooltip-compareselectedversions": "यस पृष्ठको छानिएका दुई पुनरावलोकन बीच फरक हेर्नुहोस्",
"tooltip-watch": "यो पृष्ठलाई तपाईँको अवलोकनसूचीमा थप्नुहोस्",
"tooltip-watchlistedit-normal-submit": "शीर्षकहरू हटाउने",
"widthheight": "$1 × $2",
"widthheightpage": "$1 × $2, $3 {{PLURAL:$3|पृष्ठ|पृष्ठहरू}}",
"file-info": "फाइल आकार: $1, MIME प्रकार: $2",
- "file-info-size": "$1 Ã\97 $2 पिà¤\95à¥\8dसà¥\87लहरà¥\81, फाइल आकार: $3, MIME प्रकार: $4",
+ "file-info-size": "$1 Ã\97 $2 पिà¤\95à¥\8dसà¥\87लहरà¥\82, फाइल आकार: $3, MIME प्रकार: $4",
"file-info-size-pages": "$1 × $2 पिक्सेलहरू, फाइल आकार: $3, MIME प्रकार: $4, $5 {{PLURAL:$5|पृष्ठ|पृष्ठहरू}}",
"file-nohires": "उच्च रिजोल्युशन अनुपलब्ध",
"svg-long-desc": "SVG फाइल,साधारण $1 × $2 पिक्सेलहरु, फाइल आकार: $3",
"svg-long-error": "अमान्य एसभिजी फाइल: $1",
"show-big-image": "मूल फाइल",
"show-big-image-preview": "यस पूर्व रुपको आकार: $1।",
- "show-big-image-other": "à¤\85रà¥\81 {{PLURAL:$2|resolution|रिà¤\9cà¥\8bलà¥\8dयà¥\81शनहरà¥\81}}: $1।",
+ "show-big-image-other": "à¤\85रà¥\81 {{PLURAL:$2|resolution|रिà¤\9cà¥\8bलà¥\8dयà¥\81शनहरà¥\82}}: $1।",
"show-big-image-size": "$1 × $2 पिक्सल",
"file-info-gif-looped": "चकृय गरिएको",
"file-info-gif-frames": "$1 {{PLURAL:$1|फ्रेम|फ्रेमहरु}}",
"yesterday-at": "हिजो $1मा",
"bad_image_list": "(* बाट शुरु हुने पंक्ति)को विषय सूची मात्र मान्य छ। पंक्तिको पहिलो लिङ्क नराम्रो फाइलसित लिङ्क हुनैपर्छ । एउटै पंक्तिमा कुनै पछिबाट हुने लिंकलाई अपवाद मानिनेछ अर्थात् जुन पृष्ठमा फाइल इन-लाइन हुनसक्छ।",
"metadata": "मेटाडेटा",
- "metadata-help": "यस फाà¤\87लमा à¤\85तिरिà¤\95à¥\8dत à¤\9cानà¤\95ारà¥\80हरà¥\81 à¤\9bनà¥\8d, यसलाà¤\88 बनाà¤\89न समà¥\8dà¤à¤µà¤¤à¤\83 डिà¤\9cिà¤\9fल à¤\95à¥\8dयामà¥\87रा à¤\85थवा सà¥\8dà¤\95à¥\8dयानर पà¥\8dरयà¥\8bà¤\97 à¤\97रिà¤\8fà¤\95à¥\8b हà¥\81नà¥\81परà¥\8dà¤\9b। यदि यस फाà¤\87ललाà¤\88 मà¥\82ल à¤\85वसà¥\8dथाबाà¤\9f परिवरà¥\8dतन à¤\97रिà¤\8fà¤\95à¥\8b हà¥\8b à¤à¤¨à¥\87à¤\82 यस फाइलले सम्पूर्ण विवरण प्रतिबिम्बित गर्न सक्नेछैन ।",
+ "metadata-help": "यस फाà¤\87लमा à¤\85तिरिà¤\95à¥\8dत à¤\9cानà¤\95ारà¥\80हरà¥\82 à¤\9bनà¥\8d, यसलाà¤\88 बनाà¤\89न समà¥\8dà¤à¤µà¤¤à¤\83 डिà¤\9cिà¤\9fल à¤\95à¥\8dयामà¥\87रा à¤\85थवा सà¥\8dà¤\95à¥\8dयानर पà¥\8dरयà¥\8bà¤\97 à¤\97रिà¤\8fà¤\95à¥\8b हà¥\81नà¥\81परà¥\8dà¤\9b । यदि यस फाà¤\87ललाà¤\88 मà¥\82ल à¤\85वसà¥\8dथाबाà¤\9f परिवरà¥\8dतन à¤\97रिà¤\8fà¤\95à¥\8b हà¥\8b à¤à¤¨à¥\87 यस फाइलले सम्पूर्ण विवरण प्रतिबिम्बित गर्न सक्नेछैन ।",
"metadata-expand": "लामो विबरण हेर्ने",
"metadata-collapse": "लामो विवरण लुकाउने",
- "metadata-fields": "Image metadata fields listed in this message will be included on image page display when the metadata table is collapsed.\nOthers will be hidden by default.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+ "metadata-fields": "मेटाडाटा तालिकालाई लघुरूप गरियो भने यस सन्देशमा सूचीबद्ध इएक्सआयएफ मेटाडाटा जानकारिहरू छवि प्रदर्शित हुने बेला सम्मिलित गरिने छ ।\nअन्य डिफल्ट रूपसँग लुकिरहने छ ।\n* make \n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
"exif-imagewidth": "चौडाइ",
"exif-imagelength": "उचाई",
"exif-bitspersample": "घटक प्रति बिट्स",
"minoredit": "Småplukk",
"watchthis": "Overvak sida",
"savearticle": "Lagra sida",
+ "savechanges": "Publiser endringane",
"publishpage": "Publiser sida",
"publishchanges": "Publiser endringar",
"preview": "Førehandsvising",
"Luan",
"Anderson Costa",
"LucyDiniz",
- "Tusca"
+ "Tusca",
+ "Cristofer Alves"
]
},
"tog-underline": "Sublinhar links:",
"userlogin-resetpassword-link": "Esqueceu sua senha?",
"userlogin-helplink2": "Ajuda com o login",
"userlogin-loggedin": "Você já está conectado como {{GENDER:$1|$1}}.\nUse o formulário abaixo para iniciar sessão como outro usuário.",
+ "userlogin-reauth": "Deve iniciar novamente a sessão para verificar se é {{GENDER:$1|$1}}.",
"userlogin-createanother": "Crie uma outra conta",
"createacct-emailrequired": "Endereço de e-mail",
"createacct-emailoptional": "Endereço de e-mail (opcional)",
"createacct-email-ph": "Confirme seu endereço de e-mail",
"createacct-another-email-ph": "Forneça o endereço de e-mail",
"createaccountmail": "Usar uma senha aleatória e temporária que será enviada ao endereço de e-mail especificado a seguir",
+ "createaccountmail-help": "Pode ser utilizado para criar uma conta para outra pessoa sem saber a senha.",
"createacct-realname": "Nome real (opcional)",
"createaccountreason": "Motivo:",
"createacct-reason": "Motivo",
"createacct-reason-ph": "Por que você está criando outra conta",
+ "createacct-reason-help": "Mensagem mostrada no registro de criação de conta",
"createacct-submit": "Crie sua conta",
"createacct-another-submit": "Criar conta",
+ "createacct-continue-submit": "Continuar criação de conta",
+ "createacct-another-continue-submit": "Continuar criação de conta",
"createacct-benefit-heading": "{{SITENAME}} é feita por pessoas como você.",
"createacct-benefit-body1": "{{PLURAL:$1|edição|edições}}",
"createacct-benefit-body2": "{{PLURAL:$1|página|páginas}}",
"nocookiesnew": "A conta do usuário foi criada, mas você não foi autenticado.\n{{SITENAME}} utiliza ''cookies'' para autenticar os usuários.\nVocê tem os ''cookies'' desativados no seu navegador.\nPor favor ative-os, depois autentique-se com o seu novo nome de usuário e a sua senha.",
"nocookieslogin": "Você tem os <i>cookies</i> desativados no seu navegador, e a {{SITENAME}} utiliza <i>cookies</i> para ligar os usuários às suas contas. Por favor os ative e tente novamente.",
"nocookiesfornew": "A conta de usuário não foi criada porque não foi possível confirmar a sua origem.\nCertifique-se de que tem os cookies ativados, recarregue esta página e tente novamente.",
+ "createacct-loginerror": "A conta foi criada com êxito, mas não pôde ser autenticado automaticamente. Por favor, faça o [[Special:UserLogin|início de sessão manualmente]].",
"noname": "Você não colocou um nome de usuário válido.",
"loginsuccesstitle": "Autenticado",
"loginsuccess": "'''Agora você está {{GENDER:autenticado|autenticada}} ao wiki {{SITENAME}} como \"$1\"'''.",
"botpasswords-label-delete": "Apagar",
"botpasswords-label-resetpassword": "Redefinir a sua senha",
"botpasswords-label-grants": "Permissões aplicáveis",
+ "botpasswords-help-grants": "Cada permissão da acesso à lista permissões de usuários que um usuário já tenha. Veja o [[Special:ListGrants|Lista de Permissões]] para mais informações.",
"botpasswords-label-restrictions": "Restrições de uso:",
"botpasswords-label-grants-column": "Concedido",
"botpasswords-bad-appid": "O nome de robô \"$1\" não é válido.",
"passwordreset-emailsentemail": "Se este é um endereço de e-mail registrado para a sua conta, em seguida, um e-mail de redefinição de senha será enviada.",
"passwordreset-emailsentusername": "Se houver um endereço de email associado a esta conta, ser-lhe-á enviada uma mensagem para redefinir a sua senha.",
"passwordreset-emailsent-capture2": "A redefinição da senha {{PLURAL:$1|do e-mail|dos e-mails}} foi enviada. {{PLURAL:$1|O nome de usuário e senha|A lista de nomes de usuário e senhas}} encontram-se a seguir.",
+ "passwordreset-emailerror-capture2": "O envio do e-mail {{GENDER:$2|usuário}} falhou: $1 Os {{PLURAL:$3|nome de usuário e senha|lista de nomes de usuários e senhas}} são mostrados abaixo.",
+ "passwordreset-nocaller": "Um interlocutor deve ser fornecido",
+ "passwordreset-nosuchcaller": "O interlocutor não existe: $1",
+ "passwordreset-ignored": "A redefinição da senha não foi realizada. Talvez o provedor não tenha sido configurado?",
+ "passwordreset-invalideamil": "Endereço de e-mail inválido",
+ "passwordreset-nodata": "Não foram fornecidos nome de usuário nem endereço de e-mail",
"changeemail": "Alterar ou remover endereço de email",
"changeemail-header": "Preencha este formulário para alterar seu endereço de e-mail. Se você gostaria de remover a associação de qualquer endereço de e-mail da sua conta, deixe o novo endereço de email em branco quando enviar o formulário.",
"changeemail-no-info": "Para acessar diretamente esta página você tem de estar autenticado.",
"minoredit": "Marcar como edição menor",
"watchthis": "Vigiar esta página",
"savearticle": "Salvar página",
+ "savechanges": "Salvar alterações",
"publishpage": "Publicar página",
"publishchanges": "Publicar alterações",
"preview": "Pré-visualização",
"accmailtext": "Uma senha gerada aleatoriamente para [[User talk:$1|$1]] foi enviada para $2.\n\nEla pode ser alterada na página ''[[Special:ChangePassword|de troca de senha]]'', após o início de sessão.",
"newarticle": "(Nova)",
"newarticletext": "Você seguiu um link para uma página que ainda não existe.\nPara criá-la, comece escrevendo na caixa abaixo (veja [$1 a página de ajuda] para mais informações).\nSe você chegou aqui por engano, clique no botão '''voltar''' do seu navegador.",
- "anontalkpagetext": "---- ''Esta é a página de discussão para um usuário anônimo que ainda não criou uma conta ou que não a usa, de forma que temos de utilizar o endereço de IP para identificá-lo(a). Tal endereço de IP pode ser compartilhado por vários usuários. Se você é um usuário anônimo e acha que comentários irrelevantes foram direcionados a você, por gentileza, [[Special:CreateAccount|crie uma conta]] ou [[Special:UserLogin|autentique-se]], a fim de evitar futuras confusões com outros usuários anônimos.''",
+ "anontalkpagetext": "---\n<em> Esta é a pagina de discussão para usuários anônimos que ainda não ciaram uma conta, ou para aqueles que a usa. </em>\nNós entretanto temos que usar o endereço numérico de IP para identifica-lo/a.\nEste endereço de IP pode ser compartilhado por vários usuários.\nse você é um usuário anônimo e sente que aquele comentário irrelevante foi direcionado à você, por favor [[Special:CreateAccount|Criar Conta]] ou [[Special:UserLogin|Logar]] para evitar futuras confusões com outros usuários anônimos.",
"noarticletext": "Não há conteúdo nesta página no momento.\nVocê pode [[Special:Search/{{PAGENAME}}|pesquisar pelo título desta página]] em outras páginas, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar por registros relacionados],\nou [{{fullurl:{{FULLPAGENAME}}|action=edit}} criar esta página]</span>.",
"noarticletext-nopermission": "No momento, não há conteúdo nesta página\nVocê pode [[Special:Search/{{PAGENAME}}|pesquisar pelo título desta página]] em outras páginas,\nou <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar por registros relacionados] </span>. Note que, no entanto, você não tem permissão para criar esta página.",
"missing-revision": "A revisão #$1 da página denominada \"{{FULLPAGENAME}}\" não existe.\n\nIsto é geralmente causado por seguir um link de histórico desatualizado para uma página que foi eliminada.\nOs detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de eliminação].",
"userpage-userdoesnotexist": "A conta \"<nowiki>$1</nowiki>\" não se encontra registrada.\nVerifique se deseja mesmo criar/editar esta página.",
"userpage-userdoesnotexist-view": "A conta de usuário \"$1\" não está registrada.",
"blocked-notice-logextract": "Este usuário está atualmente bloqueado.\nO registro de bloqueio mais recente é fornecido abaixo, para referência:",
- "clearyourcache": "Nota:''' Depois de salvar, você terá de limpar o ''cache'' do seu navegador para ver as alterações.\n* '''Firefox / Safari:''' pressione ''Shift'' enquanto clica em ''Recarregar'', ou pressione ''Ctrl-F5'' ou ''Ctrl-R'' (''Command-R'' para Mac);\n* '''Google Chrome:''' pressione ''Ctrl-Shift-R'' (''Command-Shift-R'' em um Mac)\n* '''Internet Explorer:''' pressione ''Ctrl'' enquanto clica em ''Recarregar'' ou pressione ''Ctrl-F5'';\n* '''Opera:''' limpe o ''cache'' em ''Ferramentas → Preferências'' (''Tools → Preferences'')",
+ "clearyourcache": "<strong>Nota:</strong> Após salvar, você pode ter que limpar o \"cache\" do seu navegador para ver as alterações.\n*<strong>Firefox / Safari:</strong> Pressione <em>Shift</em> enquanto clica <em>Recarregar</em>, ou pressione <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> no Mac)\n*<strong>Google Chorme:</strong> Pressione <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> no Mac)\n* <strong>Internet Explorer:</strong> Pressione<em>Ctrl</em> enquanto clica <em>Recarregar</em>, ou Pressione <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Vá para <em>Menu → Configurações</em> (<em>Opera → Preferencias</em> no Mac) e depois para <em>Privacidade e Segurança → Limpar dados de navegação → Imagens e arquivos em cache</em>.",
"usercssyoucanpreview": "'''Dica:''' Utilize o botão \"{{int:showpreview}}\" para testar seu novo CSS antes de salvar.",
"userjsyoucanpreview": "'''Dica:''' Utilize o botão \"{{int:showpreview}}\" para testar seu novo JavaScript antes de salvar.",
"usercsspreview": "'''Lembre-se de que você está apenas previsualizando o seu CSS particular.'''\n'''Ele ainda não foi salvo!'''",
"content-json-empty-object": "Objeto vazio",
"content-json-empty-array": "Array vazia",
"deprecated-self-close-category": "Páginas com etiquetas HTML de autofechamento não válidas",
+ "deprecated-self-close-category-desc": "A página contém tags HTML auto-fechadas inválidas, como <code><b/></code> ou <code><span/></code>. O comportamento destas mudará em breve para coincidam com as especificações do HTML5, pelo que seu uso no wikitext está obsoleto.",
"duplicate-args-warning": "<strong> Aviso: </strong> [[:$1]] está chamando [[:$2]] com mais de um valor para o parâmetro \"$3\". Será utilizado apenas o último valor fornecido.",
"duplicate-args-category": "Páginas com argumentos de predefinições duplicados",
"duplicate-args-category-desc": "A pagina contem modelos que usam argumentos duplicados, como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ou <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
"grant-group-high-volume": "Realizar grande volume de atividades",
"grant-group-customization": "Personalização e preferências",
"grant-group-administration": "Realizar ações administrativas",
+ "grant-group-private-information": "acessar os dados privados sobre você",
"grant-group-other": "Atividade diversa",
"grant-blockusers": "Bloquear e desbloquear usuários",
"grant-createaccount": "Criar contas",
"grant-highvolume": "Edição de grandes volumes",
"grant-oversight": "Ocultar usuários e revisões suprimidas",
"grant-patrol": "Patrulhar as alterações nas páginas",
+ "grant-privateinfo": "acessar informações privadas",
"grant-protect": "Proteger e desproteger páginas",
"grant-rollback": "Reverter alterações nas páginas",
"grant-sendemail": "Enviar e-mail a outros usuários",
"rightslogtext": "Este é um registro de mudanças nos privilégios de usuários.",
"action-read": "ler esta página",
"action-edit": "editar esta página",
- "action-createpage": "criar páginas",
- "action-createtalk": "criar páginas de discussão",
+ "action-createpage": "criar esta páginas",
+ "action-createtalk": "criar esta páginas de discussão",
"action-createaccount": "criar esta conta de usuário",
"action-autocreateaccount": "Criar uma conta de usuário externa automaticamente",
"action-history": "Ver o histórico desta página",
"action-applychangetags": "aplicar etiquetas juntamente com suas alterações",
"action-changetags": "adicionar e remover etiquetas arbitrárias em revisões e ''logs'' individuais",
"action-deletechangetags": "deletar marcações da base de dados",
+ "action-purge": "purgar esta página",
"nchanges": "$1 {{PLURAL:$1|alteração|alterações}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
"enhancedrc-history": "histórico",
"uploaded-event-handler-on-svg": "Não é permitido configurar atributos que manipulem eventos <code>$1=\"$2\"</code> em arquivos SVG.",
"uploaded-href-attribute-svg": "os atributos href nos ficheiros SVG só están autorizados a ligar a direccións http:// ou https://, atopado <code><$1 $2=\"$3\"></code>.",
"uploaded-href-unsafe-target-svg": "Encontrado href para dados não seguros: alvo URI <code><$1 $2=\"$3\"></code> no arquivo SVG carregado.",
+ "uploaded-animate-svg": "Encontrado a tag \"animate\" que pode estar mudando \"href\", usando o atributo \"from\" <code><$1 $2=\"$3\"></code> no arquivo SVG carregado.",
"uploadscriptednamespace": "Este aruivo SVG contém um espaço nominal probido \"$1\"",
"uploadinvalidxml": "O XML no arquivo enviado não pôde ser analisado.",
"uploadvirus": "O arquivo contém vírus!\nDetalhes: $1",
"trackingcategories-msg": "Categoria de monitoramento",
"trackingcategories-name": "Nome da mensagem",
"trackingcategories-desc": "Critérios de inclusão de categoria",
+ "restricted-displaytitle-ignored": "Páginas com títulos de exibição ignorados",
+ "restricted-displaytitle-ignored-desc": "Esta página tem um <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorado porque não é equivalente ao título verdadeiro da página.",
"noindex-category-desc": "A página não é indexada por robôs, porque possui a palavra mágica <code><nowiki>__NOINDEX__</nowiki></code> e está em um namespace onde a flag é permitida.",
"index-category-desc": "A página contém a palavra mágica <code><nowiki>__INDEX__</nowiki></code> (e está num domínio em que essa marca é permitida) e, portanto, será indexada pelos robôs mesmo quando normalmente não o seria.",
"post-expand-template-inclusion-category-desc": "O tamanho da página é superior a <code>$wgMaxArticleSize</code>, após a expansão de todas as predefinições, pelo que algumas predefinições não foram expandidas.",
"botpasswords-deleted-body": "O robô palavra-passe para o nome do robô \"$1\"do utilizador \"$2\" foi eliminado.",
"botpasswords-newpassword": "A nova palavra-passe para iniciar sessão com <strong>$1</strong> é <strong>$2</strong>. Por favor, recorde-se dela para futura referência.</em>",
"botpasswords-no-provider": "BotPasswordsSessionProvider não está disponível.",
+ "botpasswords-restriction-failed": "Restrições de senha de robô evitam esta autenticação.",
+ "botpasswords-invalid-name": "O nome de usuário especificado não contém o separador de senha de robô (\"$1\").",
+ "botpasswords-not-exist": "O usuário \"$1\" não possui uma senha de robô \"$2\".",
"resetpass_forbidden": "Não é possível alterar palavras-passe",
"resetpass_forbidden-reason": "As palavras-passe não podem ser alteradas: $1",
"resetpass-no-info": "Precisa de iniciar sessão para aceder diretamente a esta página.",
"passwordreset-emailelement": "{{GENDER:$1|Utilizador|Utilizadora}}: \n$1\n\nPalavra-passe temporária: \n$2",
"passwordreset-emailsentemail": "Se este é o endereço de correio eletrónico associado a esta conta, ser-lhe-á enviada uma palavra-passe de reposição.",
"passwordreset-emailsentusername": "Se houver um endereço de correio eletrónico associado a esta conta, ser-lhe-á enviada uma mensagem para redefinir a sua palavra-passe.",
+ "passwordreset-emailsent-capture2": "A redefinição da senha {{PLURAL:$1|do e-mail|dos e-mails}} foi enviada. {{PLURAL:$1|O nome de usuário e senha|A lista de nomes de usuário e senhas}} encontram-se a seguir.",
+ "passwordreset-emailerror-capture2": "O envio do correio {{GENDER:$2|ao usuário|à usuária}} falhou: $1 {{PLURAL:$3|O nome de usuário e senha são mostradas abaixo|A lista de nomes de usuários e senhas é mostrada abaixo}}.",
+ "passwordreset-nocaller": "Um interlocutor deve ser fornecido",
+ "passwordreset-nosuchcaller": "A pessoa que chama não existe: $1",
+ "passwordreset-ignored": "A redefinição de senha não foi realizada. Talvez o provedor não tenha sido configurado, sim?",
"passwordreset-invalideamil": "Correio eletrónico inválido",
"passwordreset-nodata": "Não foram fornecidos nome de utilizador(a) nem endereço de correio eletrónico",
"changeemail": "Alterar ou remover o endereço de correio eletrónico",
"apisandbox-loading-results": "A receber resultados da API...",
"apisandbox-request-url-label": "URL do pedido:",
"apisandbox-request-time": "Tempo de processamento: {{PLURAL:$1|$1 ms}}",
+ "apisandbox-results-fixtoken": "Corrija o identificador e envie-o novamente",
+ "apisandbox-results-fixtoken-fail": "Não foi possível recuperar o identificador \"$1\".",
+ "apisandbox-alert-page": "Os campos nesta página não são válidos.",
"apisandbox-alert-field": "O valor deste campo não é válido.",
"booksources": "Fontes bibliográficas",
"booksources-search-legend": "Pesquisar referências bibliográficas",
"trackingcategories-msg": "Categoria monitorada",
"trackingcategories-name": "Nome da mensagem",
"trackingcategories-desc": "Critérios de inclusão",
+ "restricted-displaytitle-ignored": "Páginas com títulos de exibição ignorados",
+ "restricted-displaytitle-ignored-desc": "Esta página tem um <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorado porque não é equivalente ao título verdadeiro da página.",
"noindex-category-desc": "A página não é indexada por robôs porque contém a palavra mágica <code><nowiki>__NOINDEX__</nowiki></code> e está num domínio onde o estatuto é permitido.",
"index-category-desc": "A página contém a palavra mágica <code><nowiki>__INDEX__</nowiki></code> (e está num domínio em que essa marca é permitida) e, portanto, será indexada pelos robôs mesmo quando normalmente não o seria.",
"post-expand-template-inclusion-category-desc": "O tamanho da página é superior a <code>$wgMaxArticleSize</code>, após a expansão de todas as predefinições, pelo que algumas predefinições não foram expandidas.",
"rollbacklinkcount-morethan": "reverter mais do que $1 {{PLURAL:$1|edição|edições}}",
"rollbackfailed": "A reversão falhou",
"rollback-missingparam": "Faltam parâmetros obrigatórios no pedido.",
+ "rollback-missingrevision": "Não é possível carregar os dados de revisão.",
"cantrollback": "Não foi possível reverter a edição; o último contribuidor é o único autor desta página",
"alreadyrolled": "Não foi possível reverter as edições de [[:$1]] por [[User:$2|$2]] ([[User talk:$2|discussão]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nalguém editou ou já reverteu a página.\n\nA última edição foi de [[User:$3|$3]] ([[User talk:$3|discussão]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
"editcomment": "O resumo da edição era: <em$1</em>.",
"special-characters-group-ipa": "AFI (IPA)",
"special-characters-group-symbols": "Símbolos",
"special-characters-group-greek": "Grego",
+ "special-characters-group-greekextended": "Grego estendido",
"special-characters-group-cyrillic": "Cirílico",
"special-characters-group-arabic": "Árabe",
"special-characters-group-arabicextended": "Arábico estendido",
"mw-widgets-dateinput-placeholder-month": "AAAA-MM",
"mw-widgets-titleinput-description-new-page": "a página ainda não existe.",
"mw-widgets-titleinput-description-redirect": "redirecionar para $1",
+ "sessionmanager-tie": "Não se pode combinar múltiplas solicitações de tipos de autenticação: $1.",
"sessionprovider-generic": "Sessões $1",
"sessionprovider-mediawiki-session-cookiesessionprovider": "sessões baseadas em cookie",
"sessionprovider-nocookies": "Os cookies podem estar desativados. Certifique-se de que os cookies estão ativados e inicie novamente.",
"log-action-filter-suppress-block": "Supressão de utilizadores por bloqueio",
"log-action-filter-upload-upload": "Novo carregamento",
"log-action-filter-upload-overwrite": "Recarregar",
+ "authmanager-authn-no-primary": "As informações de identificação fornecidas não podem ser autenticadas.",
+ "authmanager-authn-autocreate-failed": "A criação automática de uma conta local falhou: $1",
"authmanager-create-disabled": "A criação de contas está desativada.",
"authmanager-create-from-login": "Para criar a sua conta, por favor, preencha os campos abaixo.",
"authmanager-authplugin-setpass-failed-title": "A alteração de palavra-passe falhou",
"authpage-cannot-login-continue": "Não é possível continuar a iniciar sessão. A sua sessão pode ter expirado.",
"authpage-cannot-create": "Não é possível iniciar a criação da conta.",
"authpage-cannot-create-continue": "Não é possível continuar a criação da conta. A sua sessão pode ter expirado.",
+ "authpage-cannot-link": "Não se pode iniciar a vinculação da conta.",
+ "authpage-cannot-link-continue": "Não é possível continuar a criação da conta. A sua sessão pode ter expirado.",
"cannotauth-not-allowed-title": "Permissão negada",
"cannotauth-not-allowed": "Não possui permissão para utilizar esta página",
"changecredentials": "Alterar credenciais",
"2axterix2",
"Ата",
"Matěj Suchánek",
- "Chaduvari"
+ "Chaduvari",
+ "MarcoAurelio"
]
},
"sidebar": "{{notranslate}}",
"yourpasswordagain": "Since 1.22 no longer used in core, but may be used by some extensions. DEPRECATED",
"createacct-yourpasswordagain": "In create account form, label for field to re-enter password\n\nSee example: [{{canonicalurl:Special:UserLogin|type=signup}} Special:UserLogin?type=signup]\n{{Identical|Confirm password}}",
"createacct-yourpasswordagain-ph": "Placeholder text in create account form for re-enter password field.\n\nSee example: [{{canonicalurl:Special:UserLogin|type=signup}} Special:UserLogin?type=signup]",
- "remembermypassword": "Used as checkbox label on [[Special:ChangePassword]]. Parameters:\n* $1 - number of days\n{{Identical|Remember my login on this computer}}",
- "userlogin-remembermypassword": "The text for a check box in [[Special:UserLogin]].",
+ "userlogin-remembermypassword": "Used as checkbox label in [[Special:UserLogin]]. Parameters:\n* $1 - number of days the login session will be active if checked (Unused but used on-wiki)\n",
"userlogin-signwithsecure": "Text of link to HTTPS login form.\n\nSee example: [[Special:UserLogin]]",
"cannotloginnow-title": "Error page title shown when logging in is not possible.",
"cannotloginnow-text": "Error page text shown when logging in is not possible. Parameters:\n* $1 - Session type in use that makes it not possible to log in, from a message like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.",
"file-thumbnail-no": "Error message at [[Special:Upload]]. Parameters:\n* $1 - String (e.g. \"180px-\")",
"fileexists-forbidden": "{{doc-important|''thumb'' and ''center'' are magic words. Leave it untranslated!}}\nParameters:\n* $1 - name of the existing file",
"fileexists-shared-forbidden": "{{doc-important|''thumb'' and ''center'' are magic words. Leave it untranslated!}}\nError message at [[Special:Upload]].\nParameters:\n* $1 - name of the existing file",
+ "fileexists-no-change": "Used in [[Special:Upload]] to warn when the upload is an exact duplicate of the current version of the file.\nParameters:\n* $1 - name of the existing file",
+ "fileexists-duplicate-version": "Used in [[Special:Upload]] to warn when the upload is an exact duplicate of (an) older version(s) of the file\nParameters:\n* $1 - name of the existing file\n* $2 - Amount of matching older versions (PLURAL support)",
"file-exists-duplicate": "Used as warning in [[Special:Upload]].\nThis message is followed by the gallery of the duplicate files.\n\nParameters:\n* $1 - number of duplicate files",
"file-deleted-duplicate": "Used in [[Special:Upload]. Parameters:\n* $1 - page title of the file\n\nSee also:\n* {{msg-mw|file-deleted-duplicate-notitle}}",
"file-deleted-duplicate-notitle": "Used in [[Special:Upload]] when the title of the deleted duplicate is not available.\n\nSee also:\n* {{msg-mw|file-deleted-duplicate}}",
"filerevert-submit": "{{Identical|Revert}}",
"filerevert-success": "Message displayed when you succeed in reverting a version of a file.\n* $1 is the name of the media\n* $2 is a date\n* $3 is a time\n* $4 is an URL and must follow square bracket: [$4\n{{Identical|Revert}}",
"filerevert-badversion": "Used as error message.",
+ "filerevert-identical": "Used as error message.",
"filedelete": "Used as page title. Parameters:\n* $1 - file title\nSee also:\n* {{msg-mw|Filedelete-intro}}",
"filedelete-legend": "Used as fieldset label in the \"Delete file\" form.\n{{Identical|Delete file}}",
"filedelete-intro": "Used as introduction for FileDelete form. Parameters:\n* $1 - page title for file\nSee also:\n* {{msg-mw|Filedelete|page title}}",
"logentry-delete-revision": "{{Logentry|[[Special:Log/delete]]}}\n{{Logentryparam}}\n* $5 - the number of affected revisions of the page $3",
"logentry-delete-event-legacy": "{{Logentry|[[Special:Log/delete]]}}",
"logentry-delete-revision-legacy": "{{Logentry|[[Special:Log/delete]]}}",
- "logentry-suppress-delete": "{{Logentry}}\n\n'Hid' is a possible alternative to 'suppressed' in this message.",
+ "logentry-suppress-delete": "{{Logentry}}\n\n'Hid' is a possible alternative to 'suppressed' in this message.\n\n'''This is not a normal deletion log entry''' and is used only when the page is removed even from administrators view (on WMF wikis this is called 'oversight' or 'suppression'.",
"logentry-suppress-event": "{{Logentry}}\n{{Logentryparam}}\n* $5 - count of affected log events",
"logentry-suppress-revision": "{{Logentry}}\n{{Logentryparam}}\n* $5 - the number of affected revisions of the page $3.",
"logentry-suppress-event-legacy": "{{Logentry}}",
"passwordreset-emailtext-user": "{{SITENAME}}-pi kaq $1 sutiyuq ruraqqa {{SITENAME}}-paq ($4)\nrakiqunaykipaq yaykuna rimata kutichinatam mañakurqan. Kay qatiq ruraqpa {{PLURAL:$3|rakiqunanmi|rakiqunankunam}}\nkay e-chaski imamaytayuq kachkan:\n\n$2\n\nKay mit'alla yaykuna {{PLURAL:$3|rimaqa|rimakunaqa}} kunanmanta {{PLURAL:$5|huk p'unchawpi|$5 p'unchawpi}} mawk'ayanqam.\nYaykuspayki musuq yaykuna rimaykitam akllankiman. Pi wakiykipas kayta mañakurqaptinqa,\nicha qam ñawpaq yaykuna rimaykita yuyaspayki manaña wakinchayta munaspaykiqa,\nkay willayta mana qhawaspa mana imatapas ruraspa ñawpaq yaykuna rimaykiwanmi llamk'ayta atinki.",
"passwordreset-emailelement": "Ruraqpa sutin: \n$1\n\nMit'alla yaykuna rima: \n$2",
"passwordreset-emailsentemail": "Yaykuna rimata kutichina e-chaskiqa kachasqañam.",
- "passwordreset-emailsent-capture": "Yaykuna rimata kutichina e-chaskiqa kachasqañam, kay qatiqpi rikunki.",
- "passwordreset-emailerror-capture": "{{GENDER:$2|}}Yaykuna rimata kutichina e-chaskiqa rurasqa karqan, imatachus kay qatiqpi rikunki, ichataq kachasqa kaptin pantasqam tukurqan: $1",
"changeemail": "E-chaski imamaytata wakinchay",
"changeemail-header": "Rakiqunap e-chaski imamaytanta wakinchay",
"changeemail-no-info": "Yaykunaykim tiyan kay p'anqata chiqalla aypanaykipaq.",
"minoredit": "Kayqa uchuylla hukchaymi",
"watchthis": "Kay qillqata watiqay",
"savearticle": "P'anqata waqaychay",
+ "savechanges": "Hukchasqata waqaychay",
"preview": "Manaraq waqaychaspa qhawariy",
"showpreview": "Ñawpaqta qhawallay",
"showdiff": "Hukchasqakunata rikuchiy",
"undo-norev": "Manam atinichu llamk'apusqata kutichiyta, mana kaptinmi icha qullusqa kaptinmi.",
"undo-summary": "[[Special:Contributions/$2|$2]]-pa $1 hukchasqanta kutichisqa ([[User talk:$2|rimay]])",
"undo-summary-username-hidden": "Pakasqa ruraqpa $1 nisqa musuqchasqata kutichiy",
- "cantcreateaccounttitle": "Manam atinichu rakiqunata kichayta",
"cantcreateaccount-text": "Kay IP tiyaymanta ('''$1''') rakiquna kichariyqa [[User:$3|$3]]-pa hark'asqanmi.\n\n$3-qa nirqan kayraykum: ''$2''",
"viewpagelogs": "Kay p'anqamanta hallch'akunata qhaway",
"nohistory": "Kay p'anqamantaqa manam llamk'apuy wiñay kawsay kanchu.",
"zip-wrong-format": "Указанный файл — не ZIP-архив.",
"zip-bad": "ZIP-файл повреждён или не может быть прочитан.\nОн не может быть должным образом проверен.",
"zip-unsupported": "Этот ZIP-файл использует возможности, не поддерживаемые MediaWiki.\nОн не может быть должным образом проверен.",
- "uploadstash": "СкÑ\80Ñ\8bÑ\82наÑ\8f загÑ\80Ñ\83зка",
+ "uploadstash": "Ð\97агÑ\80Ñ\83зка во вÑ\80еменное Ñ\85Ñ\80анилиÑ\89е",
"uploadstash-summary": "Данная страница предоставляет доступ к файлам, которые были загружены (или находятся в процессе загрузки), но ещё не были опубликованы в вики. Эти файлы никому не видны, кроме загрузившего их участника.",
- "uploadstash-clear": "Очистить скрытые файлы",
- "uploadstash-nofiles": "У вас нет скрытых файлов.",
+ "uploadstash-clear": "Очистить временные файлы",
+ "uploadstash-nofiles": "У вас нет временных файлов.",
"uploadstash-badtoken": "Не удалось выполнить указанные действия. Возможно, истёк срок действия ваших учётных данных. Пожалуйста, пробуйте ещё раз.",
"uploadstash-errclear": "Очистка файлов не удалась.",
"uploadstash-refresh": "Обновить список файлов",
"uploadstash-thumbnail": "показать миниатюру",
+ "uploadstash-exception": "Не удалось сохранить загрузку во временное хранилище ($1): «$2».",
"invalid-chunk-offset": "Недопустимое смещение фрагмента",
"img-auth-accessdenied": "Доступ запрещён",
"img-auth-nopathinfo": "Отсутствует <code>PATH_INFO</code>.\nВаш сервер не настроен для передачи этих сведений.\nВозможно, он работает на основе CGI и не поддерживает <code>img_auth</code>.\nСм. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
"filerevert-submit": "Возвратить",
"filerevert-success": "'''[[Media:$1|$1]]''' был возвращён к [$4 версии от $3, $2].",
"filerevert-badversion": "Не существует предыдущей локальной версии этого файла с указанной меткой времени.",
+ "filerevert-identical": "Текущая версия файла уже идентична выбранной.",
"filedelete": "$1 — удаление",
"filedelete-legend": "Удалить файл",
"filedelete-intro": "Вы собираетесь удалить файл '''[[Media:$1|$1]]''' со всей его историей.",
"api-error-ratelimited": "Вы пытаетесь загрузить несколько файлов за более короткий промежуток времени, чем это позволено.\nПожалуйста, попробуйте ещё раз через несколько минут.",
"api-error-stashfailed": "Внутренняя ошибка: сервер не смог сохранить временный файл.",
"api-error-publishfailed": "Внутренняя ошибка: сервер не смог сохранить временный файл.",
- "api-error-stasherror": "При загрузке файла в хранилище произошла ошибка.",
+ "api-error-stasherror": "При загрузке файла во временное хранилище произошла ошибка.",
"api-error-stashedfilenotfound": "При попытке загрузить файл из временного хранилища исходный файл не найден.",
"api-error-stashpathinvalid": "Путь, по которому должен располагаться файл, загруженный во временное хранилище, некорректен.",
"api-error-stashfilestorage": "При загрузке файла во временное хранилище произошла ошибка.",
"passwordreset-capture-help": "अस्यां मञ्जूषायां यदि भवता अङ्क्यते तर्हि वि-पत्रम् (अस्थायिकूटशब्देन सह) दर्श्यते प्रेष्यते च ।",
"passwordreset-email": "वि-पत्रसङ्केतः",
"passwordreset-emailtitle": "{{SITENAME}} इत्यत्र योजकविषये",
- "passwordreset-emailtext-ip": "कोऽपि (कदाचित् भवान्/भवती, $1 अन्तर्जालसंविदः (from IP)) {{SITENAME}}($4) जालस्थानस्य कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । निम्न{{PLURAL:$3|योजकः|योजकाः}} अनेन वि-पत्रेण सह सल्लग्नः अस्ति/सल्लग्नाः सन्ति ।\n\n$2\n\n{{PLURAL:$3|एषः अल्पकालीनकूटशब्दः|एते अल्पकालीनकूटशब्दाः}} {{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} निरस्तः भविष्यति/निरस्ताः भविष्यन्ति ।\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विनतिम् अकरोत् । \n२ पूरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छिति ।",
- "passwordreset-emailtext-user": "$1 सदस्यः {{SITENAME}}($4) जालस्थानस्य कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । निम्न{{PLURAL:$3|सदस्यः|सदस्याः}} अनेन वि-पत्रेण सह सल्लग्नः अस्ति/सल्लग्नाः सन्ति ।\n\n$2\n\n{{PLURAL:$3|एषः अल्पकालीनकूटशब्दः|एते अल्पकालीनकूटशब्दाः}} {{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} निरस्तः भविष्यति/निरस्ताः भविष्यन्ति ।\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विज्ञप्तिम् अकरोत् । \n२ पूरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छिति ।",
+ "passwordreset-emailtext-ip": "कोऽपि (कदाचित् भवान्/भवती, $1 अन्तर्जालसंविदः (from IP)) {{SITENAME}}($4) जालस्थानस्य कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । अनेन वि-पत्रेण सह निम्न{{PLURAL:$3|योजकः सल्लग्नः अस्ति|योजकाः सल्लग्नाः सन्ति}} ।\n\n$2\n\n{{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} {{PLURAL:$3|एषः अल्पकालीनकूटशब्दः निरस्तः भविष्यति|एते अल्पकालीनकूटशब्दाः निरस्ताः भविष्यन्ति}} ।\n\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विनतिम् अकरोत् । \n२ पुरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छति ।",
+ "passwordreset-emailtext-user": "कोऽपि (कदाचित् भवान्/भवती, $1 अन्तर्जालसंविदः (from IP)) {{SITENAME}}($4) जालस्थानस्य कृते कूटशब्दपरिवर्तनस्य विनतिम् अकरोत् । अनेन वि-पत्रेण सह निम्न{{PLURAL:$3|योजकः सल्लग्नः अस्ति|योजकाः सल्लग्नाः सन्ति}} ।\n\n$2\n\n{{PLURAL:$5|चतुर्विंशतिघण्टासु|$5 दिनेषु}} {{PLURAL:$3|एषः अल्पकालीनकूटशब्दः निरस्तः भविष्यति|एते अल्पकालीनकूटशब्दाः निरस्ताः भविष्यन्ति}} ।\n\nअधुना प्रवेशं सम्प्राप्य कूटशब्दः परिवर्तनीयः एव । \n\nनिम्नकारणानि यदि सन्ति, तर्हि एनं सन्देशम् अवगण्यताम् ।\n\n१ कोऽपि अन्यः अत्र विनतिम् अकरोत् । \n२ पुरातनः कूटशब्दः भवतः/भवत्याः स्मरणे अस्ति ।\n३ भवान्/भवती कूटशब्दं परिवर्तयितुं नेच्छति ।",
"passwordreset-emailelement": "सदस्यनाम : \n$1\n\nअल्पकालीनकूटशब्दः : \n$2",
"passwordreset-emailsentemail": "परिवर्तितकूटशब्दस्य वि-पत्रं प्रेषितम् अस्ति ।",
"changeemail": "वि-पत्रसङ्केतः परिवर्त्यताम्",
"filerevert-submit": "Vrni",
"filerevert-success": "Datoteka '''[[Media:$1|$1]]''' je bila vrnjena na [$4 različico $3, $2].",
"filerevert-badversion": "Ne najdem preteklih lokalnih verzij datoteke s podanim časovnim žigom.",
+ "filerevert-identical": "Trenutna različica datoteke je že enaka izbrani.",
"filedelete": "Izbriši $1",
"filedelete-legend": "Brisanje datoteke",
"filedelete-intro": "Brišete datoteko '''[[Media:$1|$1]]''' skupaj z njeno celotno zgodovino.",
"filerevert-submit": "Återställ",
"filerevert-success": "'''[[Media:$1|$1]]''' har återställts till [$4 versionen från $2 kl. $3].",
"filerevert-badversion": "Det finns ingen tidigare version av filen från den angivna tidpunkten.",
+ "filerevert-identical": "Den aktuella versionen av filen är redan identisk med den valda.",
"filedelete": "Radera $1",
"filedelete-legend": "Radera fil",
"filedelete-intro": "Du håller på att radera filen '''[[Media:$1|$1]]''' tillsammans med hela dess historik.",
"filerevert-submit": "Повернути",
"filerevert-success": "'''[[Media:$1|$1]]''' був повернутий до [$4 версії від $3, $2].",
"filerevert-badversion": "Немає локальної версії цього файлу з вказаною поміткою дати і часу.",
+ "filerevert-identical": "Поточна версія файлу вже ідентична обраній.",
"filedelete": "Вилучення $1",
"filedelete-legend": "Вилучити файл",
"filedelete-intro": "Ви збираєтесь вилучити '''[[Media:$1|$1]]''' і всю його історію.",
"pageinfo-visiting-watchers": "تعداد ناظرین جنہوں نے حالیہ ترامیم کا مشاہدہ کیا",
"pageinfo-hidden-categories": "پوشیدہ {{PLURAL:$1|زمرہ|زمرہ جات}} ($1)",
"pageinfo-toolboxlink": "معلومات صفحہ",
+ "pageinfo-category-info": "زمرے کی معلومات",
+ "pageinfo-category-pages": "تعداد صفحات",
+ "pageinfo-category-subcats": "تعداد ذیلی زمرہ جات",
+ "pageinfo-category-files": "تعداد املاف",
"markaspatrolledtext": "اس صفحہ کو بطور مراجعت شدہ نشان زد کریں",
"markedaspatrollederrornotify": "بطور مراجعت نشان زد نہیں کیا جا سکا۔",
"deletedrevision": "حذف شدہ پرانی ترمیم $1۔",
"filerevert-submit": "Lùi lại",
"filerevert-success": "'''[[Media:$1|$1]]''' đã được lùi về [$4 phiên bản lúc $3, $2].",
"filerevert-badversion": "Không tồn tại phiên bản trước đó của tập tin tại thời điểm trên.",
+ "filerevert-identical": "Phiên bản hiện tại của tập tin đã y hệt với phiên bản được chọn.",
"filedelete": "Xóa $1",
"filedelete-legend": "Xóa tập tin",
"filedelete-intro": "Bạn sắp xóa tập tin '''[[Media:$1|$1]]''' cùng với tất cả lịch sử của nó.",
"suppressionlog": "廢止日誌",
"suppressionlogtext": "下面係刪除同埋由操作員牽涉到內容封鎖嘅一覽。\n睇吓[[Special:BlockList|封鎖一覽]]去睇現時進行緊嘅禁止同埋封鎖表。",
"mergehistory": "合併頁歷史",
- "mergehistory-header": "呢一版可以畀你去合併一個來源頁嘅修訂記錄到另一個新頁。\n請確認呢次更改會繼續保留嗰版之前嘅歷史版。",
+ "mergehistory-header": "呢一版可以畀你去合併一個來源頁嘅修訂記錄到另一個新頁。\n請確認呢次更改會繼續保留嗰版之前嘅歷史連續性。",
"mergehistory-box": "合併兩版嘅修訂:",
"mergehistory-from": "來源頁:",
"mergehistory-into": "目的頁:",
"changeemail-newemail": "新的电子邮件地址:",
"changeemail-newemail-help": "此字段应留空,如果您希望移除您的电子邮件地址的话。如果电子邮件地址被移除,您将无法重置忘记的密码,并将不会接收来自此wiki的电子邮件。",
"changeemail-none": "(无)",
- "changeemail-password": "你的{{SITENAME}}密码:",
+ "changeemail-password": "您的{{SITENAME}}密码:",
"changeemail-submit": "更改电子邮件地址",
"changeemail-throttled": "您最近尝试了太多次登录。请等待$1后再试。",
"changeemail-nochange": "请输入一个不同的新的电子邮件地址。",
"filerevert-submit": "恢复",
"filerevert-success": "<strong>[[Media:$1|$1]]</strong>已经恢复至[$4 $2 $3的版本]。",
"filerevert-badversion": "文件并无所请求时间戳下的早期本地版本。",
+ "filerevert-identical": "文件的当前版本已与选择的版本相同。",
"filedelete": "删除$1",
"filedelete-legend": "删除文件",
"filedelete-intro": "您将要删除文件<strong>[[Media:$1|$1]]</strong>及其全部历史。",
"logentry-delete-revision": "$1{{GENDER:$2|更改}}页面$3的{{PLURAL:$5|$5个版本}}的可见性:$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-delete": "$1{{GENDER:$2|已屏蔽}}页面$3",
"logentry-suppress-event": "$1秘密地{{GENDER:$2|更改}}$3的{{PLURAL:$5|$5个日志事件}}的可见性:$4",
"logentry-suppress-revision": "$1秘密地{{GENDER:$2|更改}}页面$3的{{PLURAL:$5|$5个版本}}的可见性:$4",
"logentry-suppress-event-legacy": "$1秘密地{{GENDER:$2|更改}}$3的日志事件的可见性",
"suppressionlog": "禁止顯示日誌",
"suppressionlogtext": "以下清單為管理員透過刪除或封鎖所隱藏的內容。\n請至 [[Special:BlockList|封鎖清單]] 取得目前已封鎖的清單。",
"mergehistory": "合併頁面歷史",
- "mergehistory-header": "這頁可以讓您合併一個來源頁面的歷史到另一個新頁面中。\n請確認這次更改會繼續保留該頁面先前的歷史版本。",
+ "mergehistory-header": "這頁可以讓您合併一個來源頁面的歷史到另一個新頁面中。\n請確認這次更改能夠繼續保留該頁面先前歷史版本的連續性。",
"mergehistory-box": "合併兩個頁面的修訂:",
"mergehistory-from": "來源頁面:",
"mergehistory-into": "目標頁面:",
private $mDb = null;
/** @var float UNIX timestamp */
- private $lastSlaveWait = 0.0;
+ private $lastReplicationWait = 0.0;
/**
* Used when creating separate schema files.
* If not set, wfGetDB() will be used.
* This function has the same parameters as wfGetDB()
*
- * @param integer $db DB index (DB_SLAVE/DB_MASTER)
+ * @param integer $db DB index (DB_REPLICA/DB_MASTER)
* @param array $groups; default: empty array
* @param string|bool $wiki; default: current wiki
* @return IDatabase
}
/**
- * Commit the transcation on a DB handle and wait for slaves to catch up
+ * Commit the transcation on a DB handle and wait for replica DBs to catch up
*
* This method makes it clear that commit() is called from a maintenance script,
* which has outermost scope. This is safe, unlike $dbw->commit() called in other places.
*
* @param IDatabase $dbw
* @param string $fname Caller name
- * @return bool Whether the slave wait succeeded
+ * @return bool Whether the replica DB wait succeeded
* @since 1.27
*/
protected function commitTransaction( IDatabase $dbw, $fname ) {
$dbw->commit( $fname );
+ try {
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $lbFactory->waitForReplication(
+ [ 'timeout' => 30, 'ifWritesSince' => $this->lastReplicationWait ]
+ );
+ $this->lastReplicationWait = microtime( true );
- $ok = wfWaitForSlaves( $this->lastSlaveWait, false, '*', 30 );
- $this->lastSlaveWait = microtime( true );
-
- return $ok;
+ return true;
+ } catch ( DBReplicationWaitError $e ) {
+ return false;
+ }
}
/**
$dbr = $this->forcedDb;
if ( $this->forcedDb === null ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
}
$this->maxCount = $dbr->selectField( $table, "MAX($field)", '', __METHOD__ );
$this->startTime = microtime( true );
}
$this->lb = wfGetLBFactory()->newMainLB();
- $db = $this->lb->getConnection( DB_SLAVE, 'dump' );
+ $db = $this->lb->getConnection( DB_REPLICA, 'dump' );
// Discourage the server from disconnecting us if it takes a long time
// to read out the big ol' batch query.
* @return bool|string Revision ID, or false if not found or error
*/
function getRevIdForTime( Title $title, $timestamp ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$id = $dbr->selectField(
[ 'revision', 'page' ],
public function execute() {
$this->output( "Fetching redirects...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select(
[ 'page' ],
[ 'page_namespace', 'page_title', 'page_latest' ],
public function execute() {
$start = '';
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$numImages = 0;
$numGood = 0;
}
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$maxUserId = 0;
do {
$this->output( "Finding spam on " . count( $wgLocalDatabases ) . " wikis\n" );
$found = false;
foreach ( $wgLocalDatabases as $wikiID ) {
- $dbr = $this->getDB( DB_SLAVE, [], $wikiID );
+ $dbr = $this->getDB( DB_REPLICA, [], $wikiID );
$count = $dbr->selectField( 'externallinks', 'COUNT(*)',
[ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
} else {
// Clean up spam on this wiki
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'externallinks', [ 'DISTINCT el_from' ],
[ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
$count = $dbr->numRows( $res );
* @throws MWException
*/
public function runTable( $params ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( array_diff( array_keys( $params ),
[ 'table', 'conds', 'index', 'callback' ] )
protected function fileExists( $name ) {
// XXX: Doesn't actually check for file existence, just presence of image record.
// This is reasonable, since cleanupImages.php only iterates over the image table.
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$row = $dbr->selectRow( 'image', [ 'img_name' ], [ 'img_name' => $name ], __METHOD__ );
return $row !== false;
public function execute() {
global $wgLocalDatabases, $wgMemc;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'interwiki', [ 'iw_prefix' ], false );
$prefixes = [];
foreach ( $res as $row ) {
public function execute() {
$pages = $this->getOption( 'maxpages' );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$totalsec = 0.0;
$scanned = 0;
global $wgUser;
$this->output( "Checking existence of old default messages..." );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( [ 'page', 'revision' ],
[ 'page_namespace', 'page_title' ],
[
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( [ 'pagelinks', 'page' ],
[
'page_id',
// 2. The Connection, through the load balancer.
try {
- $this->db = $this->lb->getConnection( DB_SLAVE, 'dump' );
+ $this->db = $this->lb->getConnection( DB_REPLICA, 'dump' );
} catch ( Exception $e ) {
throw new MWException( __METHOD__
. " rotating DB failed to obtain new database (" . $e->getMessage() . ")" );
* @param bool $shared True to pass shared-dir settings to hash func
*/
function fetchUsed( $shared ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$image = $dbr->tableName( 'image' );
$imagelinks = $dbr->tableName( 'imagelinks' );
* @param bool $shared True to pass shared-dir settings to hash func
*/
function fetchLocal( $shared ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( 'image',
[ 'img_name' ],
'',
* note that the text string itself is *not* followed by newline
*/
public function execute() {
- $db = $this->getDB( DB_SLAVE );
+ $db = $this->getDB( DB_REPLICA );
$stdin = $this->getStdin();
while ( !feof( $stdin ) ) {
$line = fgets( $stdin );
return true;
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$namespaces = [
NS_MEDIAWIKI => $dbr->buildLike( $dbr->anyString(), '.json' ),
NS_USER => $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString(), '.json' ),
$title = null;
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
// See also SpecialDoubleRedirects
$tables = [
$this->output( "Could not find registration for #$id NULL\n" );
}
}
- $this->output( "Waiting for slaves..." );
+ $this->output( "Waiting for replica DBs..." );
wfWaitForSlaves();
$this->output( " done.\n" );
} while ( $res->numRows() >= $this->mBatchSize );
public $timestamp;
/**
- * A database slave object
+ * A database replica DB object
*
* @var object
*/
$this->identifier = $this->getOption( 'identifier', wfWikiID() );
$this->compress = $this->getOption( 'compress', 'yes' ) !== 'no';
$this->skipRedirects = $this->getOption( 'skip-redirects', false ) !== false;
- $this->dbr = $this->getDB( DB_SLAVE );
+ $this->dbr = $this->getDB( DB_REPLICA );
$this->generateNamespaces();
$this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() );
$this->findex = fopen( "{$this->fspath}sitemap-index-{$this->identifier}.xml", 'wb' );
--- /dev/null
+<?php
+/**
+ * Reports the hostname of a replica DB server.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that reports the hostname of a replica DB server.
+ *
+ * @ingroup Maintenance
+ */
+class GetSlaveServer extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->addOption( "group", "Query group to check specifically" );
+ $this->addDescription( 'Report the hostname of a replica DB server' );
+ }
+
+ public function execute() {
+ global $wgAllDBsAreLocalhost;
+ if ( $wgAllDBsAreLocalhost ) {
+ $host = 'localhost';
+ } elseif ( $this->hasOption( 'group' ) ) {
+ $db = $this->getDB( DB_REPLICA, $this->getOption( 'group' ) );
+ $host = $db->getServer();
+ } else {
+ $lb = wfGetLB();
+ $i = $lb->getReaderIndex();
+ $host = $lb->getServerName( $i );
+ }
+ $this->output( "$host\n" );
+ }
+}
+
+$maintClass = "GetSlaveServer";
+require_once RUN_MAINTENANCE_IF_MAIN;
<?php
-/**
- * Reports the hostname of a slave server.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once __DIR__ . '/Maintenance.php';
-
-/**
- * Maintenance script that reports the hostname of a slave server.
- *
- * @ingroup Maintenance
- */
-class GetSlaveServer extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->addOption( "group", "Query group to check specifically" );
- $this->addDescription( 'Report the hostname of a slave server' );
- }
-
- public function execute() {
- global $wgAllDBsAreLocalhost;
- if ( $wgAllDBsAreLocalhost ) {
- $host = 'localhost';
- } elseif ( $this->hasOption( 'group' ) ) {
- $db = $this->getDB( DB_SLAVE, $this->getOption( 'group' ) );
- $host = $db->getServer();
- } else {
- $lb = wfGetLB();
- $i = $lb->getReaderIndex();
- $host = $lb->getServerName( $i );
- }
- $this->output( "$host\n" );
- }
-}
-
-$maintClass = "GetSlaveServer";
-require_once RUN_MAINTENANCE_IF_MAIN;
+// B/C alias
+require_once ( __DIR__ . '/getReplicaServer.php' );
if ( $doProtect ) {
# Protect the file
- echo "\nWaiting for slaves...\n";
- // Wait for slaves.
+ echo "\nWaiting for replica DBs...\n";
+ // Wait for replica DBs.
sleep( 2.0 ); # Why this sleep?
wfWaitForSlaves();
parent::__construct();
$this->addOption( 'quick', 'Force the update to be done in a single query' );
$this->addOption( 'background', 'Force replication-friendly mode; may be inefficient but
- avoids locking tables or lagging slaves with large updates;
- calculates counts on a slave if possible.
+ avoids locking tables or lagging replica DBs with large updates;
+ calculates counts on a replica DB if possible.
Background mode will be automatically used if multiple servers are listed
in the load balancer, usually indicating a replication environment.' );
if ( $backgroundMode ) {
$this->output( "Using replication-friendly background mode...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$chunkSize = 100;
$lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __METHOD__ );
break;
}
- // print status and let slaves catch up
+ // print status and let replica DBs catch up
$this->output( sprintf(
"id %d done (up to %d), %5.3f%% \r", $lastId, $endId, $lastId / $endId * 100 ) );
wfWaitForSlaves();
* @return int
*/
protected function doLenUpdates( $table, $idCol, $prefix, $fields ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$start = $dbw->selectField( $table, "MIN($idCol)", false, __METHOD__ );
$end = $dbw->selectField( $table, "MAX($idCol)", false, __METHOD__ );
}
// Validate the timestamps
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$this->startTimestamp = $dbr->timestamp( $this->getOption( 'starttime' ) );
$this->endTimestamp = $dbr->timestamp( $this->getOption( 'endtime' ) );
*/
protected function purgeFromLogType( $type ) {
$repo = RepoGroup::singleton()->getLocalRepo();
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
foreach ( self::$typeMappings[$type] as $logType => $logActions ) {
$this->verbose( "Scanning for {$logType}/" . implode( ',', $logActions ) . "\n" );
}
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$minTime = $dbr->timestamp( $this->getOption( 'starttime' ) );
$maxTime = $dbr->timestamp( $this->getOption( 'endtime' ) );
* @param int|bool $namespace
*/
private function purgeNamespace( $namespace = false ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$startId = 0;
if ( $namespace === false ) {
$conds = [];
$this->output( "Building content page file cache from page {$start}!\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$overwrite = $this->getOption( 'overwrite', false );
$start = ( $start > 0 )
? $start
$this->init( $count, $table );
$this->output( "Processing $table...\n" );
- $result = $this->getDB( DB_SLAVE )->select( $table, '*', [], __METHOD__ );
+ $result = $this->getDB( DB_REPLICA )->select( $table, '*', [], __METHOD__ );
foreach ( $result as $row ) {
$update = call_user_func( $callback, $row, null );
public function execute() {
// Rebuild the text index
- if ( $this->getDB( DB_SLAVE )->getType() != 'postgres' ) {
+ if ( $this->getDB( DB_REPLICA )->getType() != 'postgres' ) {
$this->output( "** Rebuilding fulltext search index (if you abort "
. "this will break searching; run this script again to fix):\n" );
$rebuildText = $this->runChild( 'RebuildTextIndex', 'rebuildtextindex.php' );
$end = str_replace( ' ', '_', $this->getOption( 'end', '' ) ); // page on img_name
$count = 0;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
do {
$conds = [ "img_name > {$dbr->addQuotes( $start )}" ];
if ( strlen( $end ) ) {
$end = null, $redirectsOnly = false, $oldRedirectsOnly = false
) {
$reportingInterval = 100;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( $start === null ) {
$start = 1;
) {
wfWaitForSlaves();
$this->output( "Deleting illegal entries from the links tables...\n" );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
do {
// Find the start of the next chunk. This is based only
// on existent page_ids.
*/
private function dfnCheckInterval( $start = null, $end = null, $batchSize = 100 ) {
$dbw = $this->getDB( DB_MASTER );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$linksTables = [ // table name => page_id field
'pagelinks' => 'pl_from',
}
public function execute() {
$this->commit = $this->hasOption( 'commit' );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$lastId = 0;
do {
# Do an initial scan for inactive accounts and report the result
$this->output( "Checking for unused user accounts...\n" );
$del = [];
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select( 'user', [ 'user_id', 'user_name', 'user_touched' ], '', __METHOD__ );
if ( $this->hasOption( 'ignore-groups' ) ) {
$excludedGroups = explode( ',', $this->getOption( 'ignore-groups' ) );
* @return bool
*/
private function isInactiveAccount( $id, $master = false ) {
- $dbo = $this->getDB( $master ? DB_MASTER : DB_SLAVE );
+ $dbo = $this->getDB( $master ? DB_MASTER : DB_REPLICA );
$checks = [
'revision' => 'rev',
'archive' => 'ar',
wfCountDown( 5 );
}
+ // We list user by user_id from one of the replica DBs
// We list user by user_id from one of the slave database
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$where = [];
if ( $this->nullsOnly ) {
* @return array
*/
private function getRollbackTitles( $user ) {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$titles = [];
$results = $dbr->select(
[ 'page', 'revision' ],
<?php
/**
- * Run a database query in batches and wait for slaves. This is used on large
+ * Run a database query in batches and wait for replica DBs. This is used on large
* wikis to prevent replication lag from going through the roof when executing
* large write queries.
*
require_once __DIR__ . '/Maintenance.php';
/**
- * Maintenance script to run a database query in batches and wait for slaves.
+ * Maintenance script to run a database query in batches and wait for replica DBs.
*
* @ingroup Maintenance
*/
public function __construct() {
parent::__construct();
$this->addDescription(
- "Run a query repeatedly until it affects 0 rows, and wait for slaves in between.\n" .
+ "Run a query repeatedly until it affects 0 rows, and wait for replica DBs in between.\n" .
"NOTE: You need to set a LIMIT clause yourself." );
}
'ss_images' => 'Number of images',
];
- // Get cached stats from slave database
- $dbr = $this->getDB( DB_SLAVE );
+ // Get cached stats from a replica DB
+ $dbr = $this->getDB( DB_REPLICA );
$stats = $dbr->selectRow( 'site_stats', '*', '', __METHOD__ );
// Get maximum size for each column
parent::__construct();
$this->addDescription( 'Send SQL queries to a MediaWiki database. ' .
'Takes a file name containing SQL as argument or runs interactively.' );
- $this->addOption( 'query', 'Run a single query instead of running interactively', false, true );
+ $this->addOption( 'query',
+ 'Run a single query instead of running interactively', false, true );
$this->addOption( 'cluster', 'Use an external cluster by name', false, true );
- $this->addOption( 'wikidb', 'The database wiki ID to use if not the current one', false, true );
- $this->addOption( 'slave', 'Use a slave server (either "any" or by name)', false, true );
+ $this->addOption( 'wikidb',
+ 'The database wiki ID to use if not the current one', false, true );
+ $this->addOption( 'replicadb',
+ 'Replica DB server to use instead of the master DB (can be "any")', false, true );
}
public function execute() {
$lb = wfGetLB( $wiki );
}
// Figure out which server to use
- if ( $this->hasOption( 'slave' ) ) {
- $server = $this->getOption( 'slave' );
- if ( $server === 'any' ) {
- $index = DB_SLAVE;
- } else {
- $index = null;
- $serverCount = $lb->getServerCount();
- for ( $i = 0; $i < $serverCount; ++$i ) {
- if ( $lb->getServerName( $i ) === $server ) {
- $index = $i;
- break;
- }
- }
- if ( $index === null ) {
- $this->error( "No slave server configured with the name '$server'.", 1 );
+ $replicaDB = $this->getOption( 'replicadb', $this->getOption( 'slave', '' ) );
+ if ( $replicaDB === 'any' ) {
+ $index = DB_REPLICA;
+ } elseif ( $replicaDB != '' ) {
+ $index = null;
+ $serverCount = $lb->getServerCount();
+ for ( $i = 0; $i < $serverCount; ++$i ) {
+ if ( $lb->getServerName( $i ) === $replicaDB ) {
+ $index = $i;
+ break;
}
}
+ if ( $index === null ) {
+ $this->error( "No replica DB server configured with the name '$server'.", 1 );
+ }
} else {
$index = DB_MASTER;
}
// Get a DB handle (with this wiki's DB selected) from the appropriate load balancer
$db = $lb->getConnection( $index, [], $wiki );
- if ( $this->hasOption( 'slave' ) && $db->getLBInfo( 'master' ) !== null ) {
- $this->error( "The server selected ({$db->getServer()}) is not a slave.", 1 );
+ if ( $replicaDB != '' && $db->getLBInfo( 'master' ) !== null ) {
+ $this->error( "The server selected ({$db->getServer()}) is not a replica DB.", 1 );
}
if ( $this->hasArg( 0 ) ) {
];
function check( $fix = false, $xml = '' ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( $fix ) {
print "Checking, will fix errors if possible...\n";
} else {
return;
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$dbw = wfGetDB( DB_MASTER );
$dbr->ping();
$dbw->ping();
}
// Find text row again
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$oldId = $dbr->selectField( 'revision', 'rev_text_id', [ 'rev_id' => $id ], __METHOD__ );
if ( !$oldId ) {
echo "Missing revision row for rev_id $id\n";
) {
$loadStyle = self::LS_CHUNKED;
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
# Set up external storage
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$row = $dbr->selectRow(
[ 'text', 'revision' ],
[ 'old_flags', 'old_text' ],
}
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$dbw = $this->getDB( DB_MASTER );
$dryRun = $this->getOption( 'dry-run' );
unset( $this->mapCache[$key] );
}
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$map = [];
$res = $dbr->select( 'revision',
[ 'rev_id', 'rev_text_id' ],
function moveToExternal( $cluster, $maxID, $minID = 1 ) {
$fname = 'moveToExternal';
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$count = $maxID - $minID + 1;
$blockSize = 1000;
protected function &getDB( $cluster, $groups = [], $wiki = false ) {
$lb = wfGetLBFactory()->getExternalLB( $cluster );
- return $lb->getConnection( DB_SLAVE );
+ return $lb->getConnection( DB_REPLICA );
}
public function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
if ( !$dbr->tableExists( 'blob_orphans' ) ) {
$this->error( "blob_orphans doesn't seem to exist, need to run trackBlobs.php first", true );
}
*/
use MediaWiki\Logger\LegacyLogger;
+use MediaWiki\MediaWikiServices;
$optionsWithArgs = RecompressTracked::getOptionsWithArgs();
require __DIR__ . '/../commandLine.inc';
public $numProcs = 1;
public $numBatches = 0;
public $pageBlobClass, $orphanBlobClass;
- public $slavePipes, $slaveProcs, $prevSlaveId;
+ public $replicaPipes, $replicaProcs, $prevReplicaId;
public $copyOnly = false;
public $isChild = false;
- public $slaveId = false;
+ public $replicaId = false;
public $noCount = false;
public $debugLog, $infoLog, $criticalLog;
public $store;
private static $optionsWithArgs = [
'procs',
- 'slave-id',
+ 'replica-id',
'debug-log',
'info-log',
'critical-log'
'procs' => 'numProcs',
'copy-only' => 'copyOnly',
'child' => 'isChild',
- 'slave-id' => 'slaveId',
+ 'replica-id' => 'replicaId',
'debug-log' => 'debugLog',
'info-log' => 'infoLog',
'critical-log' => 'criticalLog',
$this->store = new ExternalStoreDB;
if ( !$this->isChild ) {
$GLOBALS['wgDebugLogPrefix'] = "RCT M: ";
- } elseif ( $this->slaveId !== false ) {
- $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->slaveId}: ";
+ } elseif ( $this->replicaId !== false ) {
+ $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->replicaId}: ";
}
$this->pageBlobClass = function_exists( 'xdiff_string_bdiff' ) ?
'DiffHistoryBlob' : 'ConcatenatedGzipHistoryBlob';
function logToFile( $msg, $file ) {
$header = '[' . date( 'd\TH:i:s' ) . '] ' . wfHostname() . ' ' . posix_getpid();
- if ( $this->slaveId !== false ) {
- $header .= "({$this->slaveId})";
+ if ( $this->replicaId !== false ) {
+ $header .= "({$this->replicaId})";
}
$header .= ' ' . wfWikiID();
LegacyLogger::emit( sprintf( "%-50s %s\n", $header, $msg ), $file );
}
/**
- * Wait until the selected slave has caught up to the master.
- * This allows us to use the slave for things that were committed in a
+ * Wait until the selected replica DB has caught up to the master.
+ * This allows us to use the replica DB for things that were committed in a
* previous part of this batch process.
*/
function syncDBs() {
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$pos = $dbw->getMasterPos();
$dbr->masterPosWait( $pos, 100000 );
}
}
$this->syncDBs();
- $this->startSlaveProcs();
+ $this->startReplicaProcs();
$this->doAllPages();
$this->doAllOrphans();
- $this->killSlaveProcs();
+ $this->killReplicaProcs();
}
/**
* @return bool
*/
function checkTrackingTable() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
if ( !$dbr->tableExists( 'blob_tracking' ) ) {
$this->critical( "Error: blob_tracking table does not exist" );
* This necessary because text recompression is slow: loading, compressing and
* writing are all slow.
*/
- function startSlaveProcs() {
+ function startReplicaProcs() {
$cmd = 'php ' . wfEscapeShellArg( __FILE__ );
foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
- if ( $cmdOption == 'slave-id' ) {
+ if ( $cmdOption == 'replica-id' ) {
continue;
} elseif ( in_array( $cmdOption, self::$optionsWithArgs ) && isset( $this->$classOption ) ) {
$cmd .= " --$cmdOption " . wfEscapeShellArg( $this->$classOption );
' --wiki ' . wfEscapeShellArg( wfWikiID() ) .
' ' . call_user_func_array( 'wfEscapeShellArg', $this->destClusters );
- $this->slavePipes = $this->slaveProcs = [];
+ $this->replicaPipes = $this->replicaProcs = [];
for ( $i = 0; $i < $this->numProcs; $i++ ) {
$pipes = [];
$spec = [
[ 'file', 'php://stderr', 'w' ]
];
MediaWiki\suppressWarnings();
- $proc = proc_open( "$cmd --slave-id $i", $spec, $pipes );
+ $proc = proc_open( "$cmd --replica-id $i", $spec, $pipes );
MediaWiki\restoreWarnings();
if ( !$proc ) {
- $this->critical( "Error opening slave process: $cmd" );
+ $this->critical( "Error opening replica DB process: $cmd" );
exit( 1 );
}
- $this->slaveProcs[$i] = $proc;
- $this->slavePipes[$i] = $pipes[0];
+ $this->replicaProcs[$i] = $proc;
+ $this->replicaPipes[$i] = $pipes[0];
}
- $this->prevSlaveId = -1;
+ $this->prevReplicaId = -1;
}
/**
* Gracefully terminate the child processes
*/
- function killSlaveProcs() {
- $this->info( "Waiting for slave processes to finish..." );
+ function killReplicaProcs() {
+ $this->info( "Waiting for replica DB processes to finish..." );
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $this->dispatchToSlave( $i, 'quit' );
+ $this->dispatchToReplica( $i, 'quit' );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $status = proc_close( $this->slaveProcs[$i] );
+ $status = proc_close( $this->replicaProcs[$i] );
if ( $status ) {
$this->critical( "Warning: child #$i exited with status $status" );
}
}
/**
- * Dispatch a command to the next available slave.
- * This may block until a slave finishes its work and becomes available.
+ * Dispatch a command to the next available replica DB.
+ * This may block until a replica DB finishes its work and becomes available.
*/
function dispatch( /*...*/ ) {
$args = func_get_args();
- $pipes = $this->slavePipes;
+ $pipes = $this->replicaPipes;
$numPipes = stream_select( $x = [], $pipes, $y = [], 3600 );
if ( !$numPipes ) {
- $this->critical( "Error waiting to write to slaves. Aborting" );
+ $this->critical( "Error waiting to write to replica DBs. Aborting" );
exit( 1 );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $slaveId = ( $i + $this->prevSlaveId + 1 ) % $this->numProcs;
- if ( isset( $pipes[$slaveId] ) ) {
- $this->prevSlaveId = $slaveId;
- $this->dispatchToSlave( $slaveId, $args );
+ $replicaId = ( $i + $this->prevReplicaId + 1 ) % $this->numProcs;
+ if ( isset( $pipes[$replicaId] ) ) {
+ $this->prevReplicaId = $replicaId;
+ $this->dispatchToReplica( $replicaId, $args );
return;
}
}
/**
- * Dispatch a command to a specified slave
- * @param int $slaveId
+ * Dispatch a command to a specified replica DB
+ * @param int $replicaId
* @param array|string $args
*/
- function dispatchToSlave( $slaveId, $args ) {
+ function dispatchToReplica( $replicaId, $args ) {
$args = (array)$args;
$cmd = implode( ' ', $args );
- fwrite( $this->slavePipes[$slaveId], "$cmd\n" );
+ fwrite( $this->replicaPipes[$replicaId], "$cmd\n" );
}
/**
* Move all tracked pages to the new clusters
*/
function doAllPages() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$i = 0;
$startId = 0;
if ( $this->noCount ) {
if ( $current == $end || $this->numBatches >= $this->reportingInterval ) {
$this->numBatches = 0;
$this->info( "$label: $current / $end" );
- wfWaitForSlaves();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication();
}
}
* Move all orphan text to the new clusters
*/
function doAllOrphans() {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$startId = 0;
$i = 0;
if ( $this->noCount ) {
case 'quit':
return;
}
- wfWaitForSlaves();
+ MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->waitForReplication();
}
}
} else {
$titleText = '[deleted]';
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Finish any incomplete transactions
if ( !$this->copyOnly ) {
$startId = 0;
$trx = new CgzCopyTransaction( $this, $this->pageBlobClass );
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
while ( true ) {
$res = $dbr->select(
[ 'blob_tracking', 'text' ],
$this->debug( "$titleText: committing blob with " . $trx->getSize() . " items" );
$trx->commit();
$trx = new CgzCopyTransaction( $this, $this->pageBlobClass );
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
}
* @param array $conds
*/
function finishIncompleteMoves( $conds ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$startId = 0;
$conds = array_merge( $conds, [
$startId = $row->bt_text_id;
$this->moveTextRow( $row->bt_text_id, $row->bt_new_url );
if ( $row->bt_text_id % 10 == 0 ) {
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
}
$trx = new CgzCopyTransaction( $this, $this->orphanBlobClass );
- $res = wfGetDB( DB_SLAVE )->select(
+ $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $res = wfGetDB( DB_REPLICA )->select(
[ 'text', 'blob_tracking' ],
[ 'old_id', 'old_text', 'old_flags' ],
[
$this->debug( "[orphan]: committing blob with " . $trx->getSize() . " rows" );
$trx->commit();
$trx = new CgzCopyTransaction( $this, $this->orphanBlobClass );
- wfWaitForSlaves();
+ $lbFactory->waitForReplication();
}
}
$this->debug( "[orphan]: committing blob with " . $trx->getSize() . " rows" );
/* Check to see if the target text_ids have been moved already.
*
- * We originally read from the slave, so this can happen when a single
+ * We originally read from the replica DB, so this can happen when a single
* text_id is shared between multiple pages. It's rare, but possible
* if a delete/move/undelete cycle splits up a null edit.
*
function resolveStubs() {
$fname = 'resolveStubs';
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$maxID = $dbr->selectField( 'text', 'MAX(old_id)', false, $fname );
$blockSize = 10000;
$numBlocks = intval( $maxID / $blockSize ) + 1;
$stub = unserialize( $stubText );
$flags = explode( ',', $flags );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$dbw = wfGetDB( DB_MASTER );
if ( strtolower( get_class( $stub ) ) !== 'historyblobstub' ) {
class StorageTypeStats extends Maintenance {
function execute() {
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$endId = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
if ( !$endId ) {
}
$type = isset( $options['type'] ) ? $options['type'] : 'ConcatenatedGzipHistoryBlob';
-$dbr = $this->getDB( DB_SLAVE );
+$dbr = $this->getDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'revision', 'text' ],
'*',
function checkIntegrity() {
echo "Doing integrity check...\n";
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
// Scan for HistoryBlobStub objects in the text table (bug 20757)
function getTextClause() {
if ( !$this->textClause ) {
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$this->textClause = '';
foreach ( $this->clusters as $cluster ) {
if ( $this->textClause != '' ) {
*/
function trackRevisions() {
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$textClause = $this->getTextClause();
$startId = 0;
* archive table counts as orphan for our purposes.
*/
function trackOrphanText() {
- # Wait until the blob_tracking table is available in the slave
+ # Wait until the blob_tracking table is available in the replica DB
$dbw = wfGetDB( DB_MASTER );
- $dbr = wfGetDB( DB_SLAVE );
+ $dbr = wfGetDB( DB_REPLICA );
$pos = $dbw->getMasterPos();
$dbr->masterPosWait( $pos, 100000 );
echo "Searching for orphan blobs in $cluster...\n";
$lb = wfGetLBFactory()->getExternalLB( $cluster );
try {
- $extDB = $lb->getConnection( DB_SLAVE );
+ $extDB = $lb->getConnection( DB_REPLICA );
} catch ( DBConnectionError $e ) {
if ( strpos( $e->error, 'Unknown database' ) !== false ) {
echo "No database on $cluster\n";
class TidyUpBug37714 extends Maintenance {
public function execute() {
// Search for all log entries which are about changing the visability of other log entries.
- $result = $this->getDB( DB_SLAVE )->select(
+ $result = $this->getDB( DB_REPLICA )->select(
'logging',
[ 'log_id', 'log_params' ],
[
foreach ( $result as $row ) {
$ids = explode( ',', explode( "\n", $row->log_params )[0] );
- $result = $this->getDB( DB_SLAVE )->select( // Work out what log entries were changed here.
+ $result = $this->getDB( DB_REPLICA )->select( // Work out what log entries were changed here.
'logging',
'log_type',
[ 'log_id' => $ids ],
if ( $this->hasOption( 'use-master' ) ) {
$dbr = $this->getDB( DB_MASTER );
} else {
- $dbr = $this->getDB( DB_SLAVE, 'vslow' );
+ $dbr = $this->getDB( DB_REPLICA, 'vslow' );
}
$counter = new SiteStatsInit( $dbr );
$result = $counter->articles();
*/
class UpdateCollation extends Maintenance {
const BATCH_SIZE = 100; // Number of rows to process in one batch
- const SYNC_INTERVAL = 5; // Wait for slaves after this many batches
+ const SYNC_INTERVAL = 5; // Wait for replica DBs after this many batches
public $sizeHistogram = [];
global $wgCategoryCollation;
$dbw = $this->getDB( DB_MASTER );
- $dbr = $this->getDB( DB_SLAVE );
+ $dbr = $this->getDB( DB_REPLICA );
$force = $this->getOption( 'force' );
$dryRun = $this->getOption( 'dry-run' );
$verboseStats = $this->getOption( 'verbose-stats' );
$this->output( "$count done.\n" );
if ( !$dryRun && ++$batchCount % self::SYNC_INTERVAL == 0 ) {
- $this->output( "Waiting for slaves ... " );
+ $this->output( "Waiting for replica DBs ... " );
wfWaitForSlaves();
$this->output( "done\n" );
}
} while ( !wfGetLB()->pingAll() );
$this->output( "Reconnected\n\n" );
}
- # Wait for the slave to catch up
+ # Wait for the replica DB to catch up
wfWaitForSlaves();
} else {
$this->output( "cheap, skipped\n" );
$this->output( $minutes . 'm ' );
}
$this->output( sprintf( "%.2fs\n", $seconds ) );
- # Wait for the slave to catch up
+ # Wait for the replica DB to catch up
wfWaitForSlaves();
}
}
$ret = [];
$defaultOptions = User::getDefaultOptions();
- // We list user by user_id from one of the slave database
- $dbr = wfGetDB( DB_SLAVE );
+ // We list user by user_id from one of the replica DBs
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select( 'user',
[ 'user_id' ],
[],
private function CHANGER() {
$this->warn();
- // We list user by user_id from one of the slave database
- $dbr = wfGetDB( DB_SLAVE );
+ // We list user by user_id from one of the replica DBs
+ $dbr = wfGetDB( DB_REPLICA );
$result = $dbr->select( 'user',
[ 'user_id' ],
[],
// must be loaded on the bottom
'position' => 'bottom',
],
+ 'mediawiki.diff.styles' => [
+ 'position' => 'top',
+ 'styles' => [
+ 'resources/src/mediawiki/mediawiki.diff.styles.css',
+ 'resources/src/mediawiki/mediawiki.diff.styles.print.css' => [
+ 'media' => 'print'
+ ],
+ ],
+ 'targets' => [ 'desktop', 'mobile' ],
+ ],
'mediawiki.feedback' => [
'scripts' => 'resources/src/mediawiki/mediawiki.feedback.js',
'styles' => 'resources/src/mediawiki/mediawiki.feedback.css',
'jquery.spinner',
'jquery.textSelection',
'mediawiki.api',
- 'mediawiki.action.history.diff',
+ 'mediawiki.diff.styles',
'mediawiki.util',
'mediawiki.jqueryMsg',
],
'position' => 'top',
'styles' => 'resources/src/mediawiki.action/mediawiki.action.history.styles.css',
],
+ // using this module is deprecated, for diff styles use mediawiki.diff.styles instead
'mediawiki.action.history.diff' => [
'position' => 'top',
'styles' => [
- 'resources/src/mediawiki.action/mediawiki.action.history.diff.css',
- 'resources/src/mediawiki.action/mediawiki.action.history.diff.print.css' => [
+ 'resources/src/mediawiki/mediawiki.diff.styles.css',
+ 'resources/src/mediawiki/mediawiki.diff.styles.print.css' => [
'media' => 'print'
],
],
+++ /dev/null
-/*!
- * Diff rendering
- */
-table.diff {
- border: none;
- border-spacing: 4px;
- margin: 0;
- width: 100%;
- /* Ensure that colums are of equal width */
- table-layout: fixed;
-}
-
-table.diff td {
- padding: 0.33em 0.5em;
-}
-
-table.diff td.diff-marker {
- /* Compensate padding for increased font-size */
- padding: 0.25em;
-}
-
-table.diff col.diff-marker {
- width: 2%;
-}
-
-table.diff col.diff-content {
- width: 48%;
-}
-
-table.diff td div {
- /* Force-wrap very long lines such as URLs or page-widening char strings */
- word-wrap: break-word;
-}
-
-td.diff-otitle,
-td.diff-ntitle {
- text-align: center;
-}
-
-td.diff-lineno {
- font-weight: bold;
-}
-
-td.diff-marker {
- text-align: right;
- font-weight: bold;
- font-size: 1.25em;
- line-height: 1.2;
-}
-
-td.diff-addedline,
-td.diff-deletedline,
-td.diff-context {
- font-size: 88%;
- line-height: 1.6;
- vertical-align: top;
- white-space: -moz-pre-wrap;
- white-space: pre-wrap;
- border-style: solid;
- border-width: 1px 1px 1px 4px;
- border-radius: 0.33em;
-}
-
-td.diff-addedline {
- border-color: #a3d3ff;
-}
-
-td.diff-deletedline {
- border-color: #ffe49c;
-}
-
-td.diff-context {
- background: #f9f9f9;
- border-color: #e6e6e6;
- color: #333;
-}
-
-.diffchange {
- font-weight: bold;
- text-decoration: none;
-}
-
-td.diff-addedline .diffchange,
-td.diff-deletedline .diffchange {
- border-radius: 0.33em;
- padding: 0.25em 0;
-}
-
-td.diff-addedline .diffchange {
- background: #d8ecff;
-}
-
-td.diff-deletedline .diffchange {
- background: #feeec8;
-}
-
-/* Correct user & content directionality when viewing a diff */
-.diff-currentversion-title,
-.diff {
- direction: ltr;
- unicode-bidi: embed;
-}
-
-/* @noflip */ .diff-contentalign-right td {
- direction: rtl;
- unicode-bidi: embed;
-}
-
-/* @noflip */ .diff-contentalign-left td {
- direction: ltr;
- unicode-bidi: embed;
-}
-
-.diff-multi,
-.diff-otitle,
-.diff-ntitle,
-.diff-lineno {
- direction: ltr !important;
- unicode-bidi: embed;
-}
+++ /dev/null
-/*!
- * Diff rendering
- */
-td.diff-context,
-td.diff-addedline .diffchange,
-td.diff-deletedline .diffchange {
- background-color: transparent;
-}
-
-td.diff-addedline .diffchange {
- text-decoration: underline;
-}
-
-td.diff-deletedline .diffchange {
- text-decoration: line-through;
-}
--- /dev/null
+/*!
+ * Diff rendering
+ */
+table.diff {
+ border: none;
+ border-spacing: 4px;
+ margin: 0;
+ width: 100%;
+ /* Ensure that colums are of equal width */
+ table-layout: fixed;
+}
+
+table.diff td {
+ padding: 0.33em 0.5em;
+}
+
+table.diff td.diff-marker {
+ /* Compensate padding for increased font-size */
+ padding: 0.25em;
+}
+
+table.diff col.diff-marker {
+ width: 2%;
+}
+
+table.diff col.diff-content {
+ width: 48%;
+}
+
+table.diff td div {
+ /* Force-wrap very long lines such as URLs or page-widening char strings */
+ word-wrap: break-word;
+}
+
+td.diff-otitle,
+td.diff-ntitle {
+ text-align: center;
+}
+
+td.diff-lineno {
+ font-weight: bold;
+}
+
+td.diff-marker {
+ text-align: right;
+ font-weight: bold;
+ font-size: 1.25em;
+ line-height: 1.2;
+}
+
+td.diff-addedline,
+td.diff-deletedline,
+td.diff-context {
+ font-size: 88%;
+ line-height: 1.6;
+ vertical-align: top;
+ white-space: -moz-pre-wrap;
+ white-space: pre-wrap;
+ border-style: solid;
+ border-width: 1px 1px 1px 4px;
+ border-radius: 0.33em;
+}
+
+td.diff-addedline {
+ border-color: #a3d3ff;
+}
+
+td.diff-deletedline {
+ border-color: #ffe49c;
+}
+
+td.diff-context {
+ background: #f9f9f9;
+ border-color: #e6e6e6;
+ color: #333;
+}
+
+.diffchange {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+td.diff-addedline .diffchange,
+td.diff-deletedline .diffchange {
+ border-radius: 0.33em;
+ padding: 0.25em 0;
+}
+
+td.diff-addedline .diffchange {
+ background: #d8ecff;
+}
+
+td.diff-deletedline .diffchange {
+ background: #feeec8;
+}
+
+/* Correct user & content directionality when viewing a diff */
+.diff-currentversion-title,
+.diff {
+ direction: ltr;
+ unicode-bidi: embed;
+}
+
+/* @noflip */ .diff-contentalign-right td {
+ direction: rtl;
+ unicode-bidi: embed;
+}
+
+/* @noflip */ .diff-contentalign-left td {
+ direction: ltr;
+ unicode-bidi: embed;
+}
+
+.diff-multi,
+.diff-otitle,
+.diff-ntitle,
+.diff-lineno {
+ direction: ltr !important;
+ unicode-bidi: embed;
+}
--- /dev/null
+/*!
+ * Diff rendering
+ */
+td.diff-context,
+td.diff-addedline .diffchange,
+td.diff-deletedline .diffchange {
+ background-color: transparent;
+}
+
+td.diff-addedline .diffchange {
+ text-decoration: underline;
+}
+
+td.diff-deletedline .diffchange {
+ text-decoration: line-through;
+}
// Force jQuery behaviour to be for crossDomain. Otherwise jQuery would use
// XHR for a same domain request instead of <script>, which changes the request
// headers (potentially missing a cache hit), and reduces caching in general
- // since browsers cache XHR much less (if at all). And XHR means we retreive
+ // since browsers cache XHR much less (if at all). And XHR means we retrieve
// text, so we'd need to $.globalEval, which then messes up line numbers.
crossDomain: true,
cache: true
}
}
+ /**
+ * Evaluate a batch of load.php responses retrieved from mw.loader.store.
+ *
+ * @private
+ * @param {string[]} implementations Array containing pieces of JavaScript code in the
+ * form of calls to mw.loader#implement().
+ * @param {Function} cb Callback in case of failure
+ * @param {Error} cb.err
+ */
+ function batchEval( implementations, cb ) {
+ if ( !implementations.length ) {
+ return;
+ }
+ mw.requestIdleCallback( function iterate( deadline ) {
+ while ( implementations[ 0 ] && deadline.timeRemaining() > 5 ) {
+ try {
+ $.globalEval( implementations.shift() );
+ } catch ( err ) {
+ cb( err );
+ return;
+ }
+ }
+ if ( implementations[ 0 ] ) {
+ mw.requestIdleCallback( iterate );
+ }
+ } );
+ }
+
/* Public Members */
return {
/**
* @protected
*/
work: function () {
- var q, batch, concatSource, origBatch;
+ var q, batch, implementations, sourceModules;
batch = [];
}
}
+ // Now that the queue has been processed into a batch, clear the queue.
+ // This MUST happen before we initiate any eval or network request. Otherwise,
+ // it is possible for a cached script to instantly trigger the same work queue
+ // again; all before we've cleared it causing each request to include modules
+ // which are already loaded.
+ queue = [];
+
+ if ( !batch.length ) {
+ return;
+ }
+
mw.loader.store.init();
if ( mw.loader.store.enabled ) {
- concatSource = [];
- origBatch = batch;
+ implementations = [];
+ sourceModules = [];
batch = $.grep( batch, function ( module ) {
- var source = mw.loader.store.get( module );
- if ( source ) {
- concatSource.push( source );
+ var implementation = mw.loader.store.get( module );
+ if ( implementation ) {
+ implementations.push( implementation );
+ sourceModules.push( module );
return false;
}
return true;
} );
- try {
- $.globalEval( concatSource.join( ';' ) );
- } catch ( err ) {
+ batchEval( implementations, function ( err ) {
// Not good, the cached mw.loader.implement calls failed! This should
// never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
// Depending on how corrupt the string is, it is likely that some
// modules' implement() succeeded while the ones after the error will
// never run and leave their modules in the 'loading' state forever.
-
// Since this is an error not caused by an individual module but by
// something that infected the implement call itself, don't take any
// risks and clear everything in this cache.
mw.loader.store.clear();
- // Re-add the ones still pending back to the batch and let the server
- // repopulate these modules to the cache.
- // This means that at most one module will be useless (the one that had
- // the error) instead of all of them.
mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
- origBatch = $.grep( origBatch, function ( module ) {
+
+ // Re-add the failed ones that are still pending back to the batch
+ var failed = $.grep( sourceModules, function ( module ) {
return registry[ module ].state === 'loading';
} );
- batch = batch.concat( origBatch );
- }
+ batchRequest( failed );
+ } );
}
- // Now that the queue has been processed into a batch, clear up the queue.
- // This MUST happen before we initiate any network request. Else it's possible
- // that a script will be locally cached, instantly load, and work the queue
- // again; all before we've cleared it causing each request to include modules
- // which are already loaded.
- queue = [];
-
batchRequest( batch );
},
hexRnds[ i ] = byteToHex[ rnds[ i ] ];
}
- // Concatenation of two random integers with entrophy n and m
- // returns a string with entrophy n+m if those strings are independent
+ // Concatenation of two random integers with entropy n and m
+ // returns a string with entropy n+m if those strings are independent
return hexRnds.join( '' );
},
$wgDBserver, $dbw->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
$dbr = $lb->getConnection( DB_SLAVE );
- $this->assertTrue( $dbr->getLBInfo( 'slave' ), 'slave shows as slave' );
+ $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
$this->assertEquals(
$wgDBserver, $dbr->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
$this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
$dbr = $lb->getConnection( DB_SLAVE );
- $this->assertTrue( $dbr->getLBInfo( 'slave' ), 'slave shows as slave' );
+ $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
$factory->shutdown();
$lb->closeAll();
] ],
[ [
'supportsBucketing' => true,
- 'tmpBucketedThumbCache' => [ 1024 => '/tmp/shouldnotexist' + rand() ],
+ 'tmpBucketedThumbCache' => [ 1024 => '/tmp/shouldnotexist' . rand() ],
'thumbnailBucket' => 1024,
'physicalWidth' => 2048,
'expectedPath' => 'fsFilePath',
return [
// $data, $sampleRate, $seed, $expectWrite
- [ $unsampled, 1, 0 /*0.44*/, $unsampled ],
- [ $sampled, 1, 0 /*0.44*/, null ],
- [ $sampled, 1, 4 /*0.03*/, $sampled ],
- [ $unsampled, 0.1, 4 /*0.03*/, $sampled ],
- [ $sampled, 0.5, 0 /*0.44*/, null ],
- [ $sampled, 0.5, 4 /*0.03*/, $sampled ],
+ [ $unsampled, 1, 0 /*0.44*/, true ],
+ [ $sampled, 1, 0 /*0.44*/, false ],
+ [ $sampled, 1, 4 /*0.03*/, true ],
+ [ $unsampled, 0.1, 0 /*0.44*/, false ],
+ [ $sampled, 0.5, 0 /*0.44*/, false ],
+ [ $sampled, 0.5, 4 /*0.03*/, false ],
];
}
+
+ public function testSetSamplingRates() {
+ $matching = new StatsdData();
+ $matching->setKey( 'foo.bar' );
+ $matching->setValue( 1 );
+
+ $nonMatching = new StatsdData();
+ $nonMatching->setKey( 'oof.bar' );
+ $nonMatching->setValue( 1 );
+
+ $sender = $this->getMock( 'Liuggio\StatsdClient\Sender\SenderInterface' );
+ $sender->expects( $this->any() )->method( 'open' )->will( $this->returnValue( true ) );
+ $sender->expects( $this->once() )->method( 'write' )->with( $this->anything(),
+ $this->equalTo( $nonMatching ) );
+
+ $client = new SamplingStatsdClient( $sender );
+ $client->setSamplingRates( [ 'foo.*' => 0.2 ] );
+
+ mt_srand( 0 ); // next random is 0.44
+ $client->send( $matching );
+ mt_srand( 0 );
+ $client->send( $nonMatching );
+ }
}