# Editors
*.kate-swp
*~
+\#*#
+.#*
.*.swp
.project
cscope.files
uz, vi.
* Added 'CategoryAfterPageAdded' and 'CategoryAfterPageRemoved' hooks.
* Added 'HistoryRevisionTools' and 'DiffRevisionTools' hooks.
+* Added 'SpecialSearchResultsPrepend' and 'SpecialSearchResultsAppend' hooks.
* (bug 33186) Add image rotation api "imagerotate"
* (bug 34040) Add "User rights management" link on user page toolbox.
* (bug 45526) Add QUnit assertion helper "QUnit.assert.htmlEqual" for asserting
* $wgRedirectScript was removed. It was unused.
* Removed $wgLocalMessageCacheSerialized, it is now always true.
* When $wgUseVFormUserLogin is true, the redesign of Special:UserLogin is
- activated.
+ activated; when $wgUseVFormCreateAccount is true, the redesign of
+ Special:UserLogin/signup is activated.
* $wgVectorUseIconWatch is now enabled by default.
=== New features in 1.22 ===
preference). This feature was moved from the Vector extension, and is now part
of core for all skins. Take care when upgrading that you don't use an older
version of the Vector extension as this feature may conflict.
-* New version of Special:UserLogin form. It is opt-in for now, controlled by
- the $wgUseVFormUserLogin setting or a 'useNew' URL parameter trigger.
-* Added 'SpecialSearchResultsPrepend' and 'SpecialSearchResultsAppend' hooks.
+* New 'mediawiki.ui' CSS module providing mw-ui-* styles for buttons and a
+ compact vertical form layout.
+* New versions of login (Special:UserLogin) and create account
+ (Special:UserLogin/signup) forms. They are opt-in for now, controlled by
+ the $wgUseVFormUserLogin and $wgUseVFormCreateAccount settings or a 'useNew'
+ URL parameter trigger.
* (bug 23343) Implemented ability to apply IP blocks to the contents of X-Forwarded-For headers
by adding a new configuration variable $wgApplyIpBlocksToXff (disabled by default).
* The new hook 'APIGetPossibleErrors' to modify the list of possible errors was
an accesskey in it already). As such it now rountrips. Creating a link with a
message as tooltip, grabbing the title attribute and using it to create
another portlet will work as expected.
+* (bug 6747) {{ROOTPAGENAME}} introduced, contains the name of the topmost
+ page without namespace.
=== Bug fixes in 1.22 ===
* Disable Special:PasswordReset when $wgEnableEmail. Previously one could still
* Pager's properly validate which fields are allowed to be sorted on.
* mw.util.tooltipAccessKeyRegexp: The regex now matches "option-" as well.
Support for Mac "option" was added in 1.16, but the regex was never updated.
+* (bug 46768) Usernames of blocking users now display correctly, even if numeric.
=== API changes in 1.22 ===
* (bug 46626) xmldoublequote parameter was removed. Because of a bug, the
longer be), and will no longer choke on booleans.
* action=opensearch no longer silently ignores the format parameter.
* action=opensearch now supports format=jsonfm.
+* list=usercontribs&ucprop=ids will now include the parent revision id.
=== Languages updated in 1.22===
'ConfEditorToken' => 'includes/ConfEditor.php',
'Cookie' => 'includes/Cookie.php',
'CookieJar' => 'includes/Cookie.php',
- 'MWCryptRand' => 'includes/CryptRand.php',
'CurlHttpRequest' => 'includes/HttpFunctions.php',
'DeferrableUpdate' => 'includes/DeferredUpdates.php',
'DeferredUpdates' => 'includes/DeferredUpdates.php',
'EnhancedChangesList' => 'includes/ChangesList.php',
'ErrorPageError' => 'includes/Exception.php',
'ExplodeIterator' => 'includes/StringUtils.php',
- 'ExternalStore' => 'includes/externalstore/ExternalStore.php',
- 'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
- 'ExternalStoreHttp' => 'includes/externalstore/ExternalStoreHttp.php',
- 'ExternalStoreMedium' => 'includes/externalstore/ExternalStoreMedium.php',
- 'ExternalStoreMwstore' => 'includes/externalstore/ExternalStoreMwstore.php',
'FakeTitle' => 'includes/FakeTitle.php',
'Fallback' => 'includes/Fallback.php',
'FatalError' => 'includes/Exception.php',
'Hooks' => 'includes/Hooks.php',
'Html' => 'includes/Html.php',
'HTMLApiField' => 'includes/HTMLForm.php',
+ 'HTMLButtonField' => 'includes/HTMLForm.php',
'HTMLCheckField' => 'includes/HTMLForm.php',
'HTMLCheckMatrix' => 'includes/HTMLForm.php',
'HTMLEditTools' => 'includes/HTMLForm.php',
'Message' => 'includes/Message.php',
'MessageBlobStore' => 'includes/MessageBlobStore.php',
'MimeMagic' => 'includes/MimeMagic.php',
+ 'MWCryptRand' => 'includes/MWCryptRand.php',
'MWException' => 'includes/Exception.php',
'MWExceptionHandler' => 'includes/Exception.php',
'MWFunction' => 'includes/MWFunction.php',
'WikiDiff3' => 'includes/diff/WikiDiff3.php',
'WordLevelDiff' => 'includes/diff/DairikiDiff.php',
+ # includes/externalstore
+ 'ExternalStore' => 'includes/externalstore/ExternalStore.php',
+ 'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
+ 'ExternalStoreHttp' => 'includes/externalstore/ExternalStoreHttp.php',
+ 'ExternalStoreMedium' => 'includes/externalstore/ExternalStoreMedium.php',
+ 'ExternalStoreMwstore' => 'includes/externalstore/ExternalStoreMwstore.php',
+
# includes/filebackend
'FileBackendGroup' => 'includes/filebackend/FileBackendGroup.php',
'FileBackend' => 'includes/filebackend/FileBackend.php',
'UserloginTemplate' => 'includes/templates/Userlogin.php',
'UserloginTemplateVForm' => 'includes/templates/UserloginVForm.php',
'UsercreateTemplate' => 'includes/templates/Usercreate.php',
+ 'UsercreateTemplateVForm' => 'includes/templates/UsercreateVForm.php',
# includes/upload
'UploadBase' => 'includes/upload/UploadBase.php',
public function setBlocker( $user ) {
$this->blocker = $user;
}
+
+ /**
+ * Get the key and parameters for the corresponding error message.
+ *
+ * @since 1.22
+ * @param IContextSource $context
+ * @return array
+ */
+ public function getPermissionsError( IContextSource $context ) {
+ $blocker = $this->getBlocker();
+ if ( $blocker instanceof User ) { // local user
+ $blockerUserpage = $blocker->getUserPage();
+ $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
+ } else { // foreign user
+ $link = $blocker;
+ }
+
+ $reason = $this->mReason;
+ if ( $reason == '' ) {
+ $reason = $context->msg( 'blockednoreason' )->text();
+ }
+
+ /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
+ * This could be a username, an IP range, or a single IP. */
+ $intended = $this->getTarget();
+
+ $lang = $context->getLanguage();
+ return array(
+ $this->mAuto ? 'autoblockedtext' : 'blockedtext',
+ $link,
+ $reason,
+ $context->getRequest()->getIP(),
+ $this->getByName(),
+ $this->getId(),
+ $lang->formatExpiry( $this->mExpiry ),
+ (string)$intended,
+ $lang->timeanddate( wfTimestamp( TS_MW, $this->mTimestamp ), true ),
+ );
+ }
}
*/
private function preCacheMessages() {
if ( !isset( $this->message ) ) {
- foreach ( explode( ' ', 'cur diff hist last blocklink history ' .
- 'semicolon-separator pipe-separator' ) as $msg ) {
+ foreach ( array(
+ 'cur', 'diff', 'hist', 'last', 'blocklink', 'history',
+ 'semicolon-separator', 'pipe-separator' ) as $msg
+ ) {
$this->message[$msg] = $this->msg( $msg )->escaped();
}
}
+++ /dev/null
-<?php
-/**
- * A cryptographic random generator class used for generating secret keys
- *
- * This is based in part on Drupal code as well as what we used in our own code
- * prior to introduction of this class.
- *
- * 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
- *
- * @author Daniel Friesen
- * @file
- */
-
-class MWCryptRand {
-
- /**
- * Minimum number of iterations we want to make in our drift calculations.
- */
- const MIN_ITERATIONS = 1000;
-
- /**
- * Number of milliseconds we want to spend generating each separate byte
- * of the final generated bytes.
- * This is used in combination with the hash length to determine the duration
- * we should spend doing drift calculations.
- */
- const MSEC_PER_BYTE = 0.5;
-
- /**
- * Singleton instance for public use
- */
- protected static $singleton = null;
-
- /**
- * The hash algorithm being used
- */
- protected $algo = null;
-
- /**
- * The number of bytes outputted by the hash algorithm
- */
- protected $hashLength = null;
-
- /**
- * A boolean indicating whether the previous random generation was done using
- * cryptographically strong random number generator or not.
- */
- protected $strong = null;
-
- /**
- * Initialize an initial random state based off of whatever we can find
- */
- protected function initialRandomState() {
- // $_SERVER contains a variety of unstable user and system specific information
- // It'll vary a little with each page, and vary even more with separate users
- // It'll also vary slightly across different machines
- $state = serialize( $_SERVER );
-
- // To try vary the system information of the state a bit more
- // by including the system's hostname into the state
- $state .= wfHostname();
-
- // Try to gather a little entropy from the different php rand sources
- $state .= rand() . uniqid( mt_rand(), true );
-
- // Include some information about the filesystem's current state in the random state
- $files = array();
-
- // We know this file is here so grab some info about ourselves
- $files[] = __FILE__;
-
- // We must also have a parent folder, and with the usual file structure, a grandparent
- $files[] = __DIR__;
- $files[] = dirname( __DIR__ );
-
- // The config file is likely the most often edited file we know should be around
- // so include its stat info into the state.
- // The constant with its location will almost always be defined, as WebStart.php defines
- // MW_CONFIG_FILE to $IP/LocalSettings.php unless being configured with MW_CONFIG_CALLBACK (eg. the installer)
- if ( defined( 'MW_CONFIG_FILE' ) ) {
- $files[] = MW_CONFIG_FILE;
- }
-
- foreach ( $files as $file ) {
- wfSuppressWarnings();
- $stat = stat( $file );
- wfRestoreWarnings();
- if ( $stat ) {
- // stat() duplicates data into numeric and string keys so kill off all the numeric ones
- foreach ( $stat as $k => $v ) {
- if ( is_numeric( $k ) ) {
- unset( $k );
- }
- }
- // The absolute filename itself will differ from install to install so don't leave it out
- if ( ( $path = realpath( $file ) ) !== false ) {
- $state .= $path;
- } else {
- $state .= $file;
- }
- $state .= implode( '', $stat );
- } else {
- // The fact that the file isn't there is worth at least a
- // minuscule amount of entropy.
- $state .= '0';
- }
- }
-
- // Try and make this a little more unstable by including the varying process
- // id of the php process we are running inside of if we are able to access it
- if ( function_exists( 'getmypid' ) ) {
- $state .= getmypid();
- }
-
- // If available try to increase the instability of the data by throwing in
- // the precise amount of memory that we happen to be using at the moment.
- if ( function_exists( 'memory_get_usage' ) ) {
- $state .= memory_get_usage( true );
- }
-
- // It's mostly worthless but throw the wiki's id into the data for a little more variance
- $state .= wfWikiID();
-
- // If we have a secret key or proxy key set then throw it into the state as well
- global $wgSecretKey, $wgProxyKey;
- if ( $wgSecretKey ) {
- $state .= $wgSecretKey;
- } elseif ( $wgProxyKey ) {
- $state .= $wgProxyKey;
- }
-
- return $state;
- }
-
- /**
- * Randomly hash data while mixing in clock drift data for randomness
- *
- * @param string $data The data to randomly hash.
- * @return String The hashed bytes
- * @author Tim Starling
- */
- protected function driftHash( $data ) {
- // Minimum number of iterations (to avoid slow operations causing the loop to gather little entropy)
- $minIterations = self::MIN_ITERATIONS;
- // Duration of time to spend doing calculations (in seconds)
- $duration = ( self::MSEC_PER_BYTE / 1000 ) * $this->hashLength();
- // Create a buffer to use to trigger memory operations
- $bufLength = 10000000;
- $buffer = str_repeat( ' ', $bufLength );
- $bufPos = 0;
-
- // Iterate for $duration seconds or at least $minIterations number of iterations
- $iterations = 0;
- $startTime = microtime( true );
- $currentTime = $startTime;
- while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
- // Trigger some memory writing to trigger some bus activity
- // This may create variance in the time between iterations
- $bufPos = ( $bufPos + 13 ) % $bufLength;
- $buffer[$bufPos] = ' ';
- // Add the drift between this iteration and the last in as entropy
- $nextTime = microtime( true );
- $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
- $data .= $delta;
- // Every 100 iterations hash the data and entropy
- if ( $iterations % 100 === 0 ) {
- $data = sha1( $data );
- }
- $currentTime = $nextTime;
- $iterations++;
- }
- $timeTaken = $currentTime - $startTime;
- $data = $this->hash( $data );
-
- wfDebug( __METHOD__ . ": Clock drift calculation " .
- "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
- "iterations=$iterations, " .
- "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)\n" );
- return $data;
- }
-
- /**
- * Return a rolling random state initially build using data from unstable sources
- * @return string A new weak random state
- */
- protected function randomState() {
- static $state = null;
- if ( is_null( $state ) ) {
- // Initialize the state with whatever unstable data we can find
- // It's important that this data is hashed right afterwards to prevent
- // it from being leaked into the output stream
- $state = $this->hash( $this->initialRandomState() );
- }
- // Generate a new random state based on the initial random state or previous
- // random state by combining it with clock drift
- $state = $this->driftHash( $state );
- return $state;
- }
-
- /**
- * Decide on the best acceptable hash algorithm we have available for hash()
- * @throws MWException
- * @return String A hash algorithm
- */
- protected function hashAlgo() {
- if ( !is_null( $this->algo ) ) {
- return $this->algo;
- }
-
- $algos = hash_algos();
- $preference = array( 'whirlpool', 'sha256', 'sha1', 'md5' );
-
- foreach ( $preference as $algorithm ) {
- if ( in_array( $algorithm, $algos ) ) {
- $this->algo = $algorithm;
- wfDebug( __METHOD__ . ": Using the {$this->algo} hash algorithm.\n" );
- return $this->algo;
- }
- }
-
- // We only reach here if no acceptable hash is found in the list, this should
- // be a technical impossibility since most of php's hash list is fixed and
- // some of the ones we list are available as their own native functions
- // But since we already require at least 5.2 and hash() was default in
- // 5.1.2 we don't bother falling back to methods like sha1 and md5.
- throw new MWException( "Could not find an acceptable hashing function in hash_algos()" );
- }
-
- /**
- * Return the byte-length output of the hash algorithm we are
- * using in self::hash and self::hmac.
- *
- * @return int Number of bytes the hash outputs
- */
- protected function hashLength() {
- if ( is_null( $this->hashLength ) ) {
- $this->hashLength = strlen( $this->hash( '' ) );
- }
- return $this->hashLength;
- }
-
- /**
- * Generate an acceptably unstable one-way-hash of some text
- * making use of the best hash algorithm that we have available.
- *
- * @param $data string
- * @return String A raw hash of the data
- */
- protected function hash( $data ) {
- return hash( $this->hashAlgo(), $data, true );
- }
-
- /**
- * Generate an acceptably unstable one-way-hmac of some text
- * making use of the best hash algorithm that we have available.
- *
- * @param $data string
- * @param $key string
- * @return String A raw hash of the data
- */
- protected function hmac( $data, $key ) {
- return hash_hmac( $this->hashAlgo(), $data, $key, true );
- }
-
- /**
- * @see self::wasStrong()
- */
- public function realWasStrong() {
- if ( is_null( $this->strong ) ) {
- throw new MWException( __METHOD__ . ' called before generation of random data' );
- }
- return $this->strong;
- }
-
- /**
- * @see self::generate()
- */
- public function realGenerate( $bytes, $forceStrong = false ) {
- wfProfileIn( __METHOD__ );
-
- wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " . wfGetAllCallers( 5 ) . "\n" );
-
- $bytes = floor( $bytes );
- static $buffer = '';
- if ( is_null( $this->strong ) ) {
- // Set strength to false initially until we know what source data is coming from
- $this->strong = true;
- }
-
- if ( strlen( $buffer ) < $bytes ) {
- // If available make use of mcrypt_create_iv URANDOM source to generate randomness
- // On unix-like systems this reads from /dev/urandom but does it without any buffering
- // and bypasses openbasedir restrictions, so it's preferable to reading directly
- // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
- // entropy so this is also preferable to just trying to read urandom because it may work
- // on Windows systems as well.
- if ( function_exists( 'mcrypt_create_iv' ) ) {
- wfProfileIn( __METHOD__ . '-mcrypt' );
- $rem = $bytes - strlen( $buffer );
- $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
- if ( $iv === false ) {
- wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" );
- } else {
- $buffer .= $iv;
- wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) . " bytes of randomness.\n" );
- }
- wfProfileOut( __METHOD__ . '-mcrypt' );
- }
- }
-
- if ( strlen( $buffer ) < $bytes ) {
- // If available make use of openssl's random_pseudo_bytes method to attempt to generate randomness.
- // However don't do this on Windows with PHP < 5.3.4 due to a bug:
- // http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php
- // http://git.php.net/?p=php-src.git;a=commitdiff;h=cd62a70863c261b07f6dadedad9464f7e213cad5
- if ( function_exists( 'openssl_random_pseudo_bytes' )
- && ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) )
- ) {
- wfProfileIn( __METHOD__ . '-openssl' );
- $rem = $bytes - strlen( $buffer );
- $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
- if ( $openssl_bytes === false ) {
- wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" );
- } else {
- $buffer .= $openssl_bytes;
- wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " . strlen( $openssl_bytes ) . " bytes of " . ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
- }
- if ( strlen( $buffer ) >= $bytes ) {
- // openssl tells us if the random source was strong, if some of our data was generated
- // using it use it's say on whether the randomness is strong
- $this->strong = !!$openssl_strong;
- }
- wfProfileOut( __METHOD__ . '-openssl' );
- }
- }
-
- // Only read from urandom if we can control the buffer size or were passed forceStrong
- if ( strlen( $buffer ) < $bytes && ( function_exists( 'stream_set_read_buffer' ) || $forceStrong ) ) {
- wfProfileIn( __METHOD__ . '-fopen-urandom' );
- $rem = $bytes - strlen( $buffer );
- if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
- wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom without control over the buffer size.\n" );
- }
- // /dev/urandom is generally considered the best possible commonly
- // available random source, and is available on most *nix systems.
- wfSuppressWarnings();
- $urandom = fopen( "/dev/urandom", "rb" );
- wfRestoreWarnings();
-
- // Attempt to read all our random data from urandom
- // php's fread always does buffered reads based on the stream's chunk_size
- // so in reality it will usually read more than the amount of data we're
- // asked for and not storing that risks depleting the system's random pool.
- // If stream_set_read_buffer is available set the chunk_size to the amount
- // of data we need. Otherwise read 8k, php's default chunk_size.
- if ( $urandom ) {
- // php's default chunk_size is 8k
- $chunk_size = 1024 * 8;
- if ( function_exists( 'stream_set_read_buffer' ) ) {
- // If possible set the chunk_size to the amount of data we need
- stream_set_read_buffer( $urandom, $rem );
- $chunk_size = $rem;
- }
- $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
- $buffer .= $random_bytes;
- fclose( $urandom );
- wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) . " bytes of randomness.\n" );
- if ( strlen( $buffer ) >= $bytes ) {
- // urandom is always strong, set to true if all our data was generated using it
- $this->strong = true;
- }
- } else {
- wfDebug( __METHOD__ . ": /dev/urandom could not be opened.\n" );
- }
- wfProfileOut( __METHOD__ . '-fopen-urandom' );
- }
-
- // If we cannot use or generate enough data from a secure source
- // use this loop to generate a good set of pseudo random data.
- // This works by initializing a random state using a pile of unstable data
- // and continually shoving it through a hash along with a variable salt.
- // We hash the random state with more salt to avoid the state from leaking
- // out and being used to predict the /randomness/ that follows.
- if ( strlen( $buffer ) < $bytes ) {
- wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" );
- }
- while ( strlen( $buffer ) < $bytes ) {
- wfProfileIn( __METHOD__ . '-fallback' );
- $buffer .= $this->hmac( $this->randomState(), mt_rand() );
- // This code is never really cryptographically strong, if we use it
- // at all, then set strong to false.
- $this->strong = false;
- wfProfileOut( __METHOD__ . '-fallback' );
- }
-
- // Once the buffer has been filled up with enough random data to fulfill
- // the request shift off enough data to handle the request and leave the
- // unused portion left inside the buffer for the next request for random data
- $generated = substr( $buffer, 0, $bytes );
- $buffer = substr( $buffer, $bytes );
-
- wfDebug( __METHOD__ . ": " . strlen( $buffer ) . " bytes of randomness leftover in the buffer.\n" );
-
- wfProfileOut( __METHOD__ );
- return $generated;
- }
-
- /**
- * @see self::generateHex()
- */
- public function realGenerateHex( $chars, $forceStrong = false ) {
- // hex strings are 2x the length of raw binary so we divide the length in half
- // odd numbers will result in a .5 that leads the generate() being 1 character
- // short, so we use ceil() to ensure that we always have enough bytes
- $bytes = ceil( $chars / 2 );
- // Generate the data and then convert it to a hex string
- $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
- // A bit of paranoia here, the caller asked for a specific length of string
- // here, and it's possible (eg when given an odd number) that we may actually
- // have at least 1 char more than they asked for. Just in case they made this
- // call intending to insert it into a database that does truncation we don't
- // want to give them too much and end up with their database and their live
- // code having two different values because part of what we gave them is truncated
- // hence, we strip out any run of characters longer than what we were asked for.
- return substr( $hex, 0, $chars );
- }
-
- /** Publicly exposed static methods **/
-
- /**
- * Return a singleton instance of MWCryptRand
- * @return MWCryptRand
- */
- protected static function singleton() {
- if ( is_null( self::$singleton ) ) {
- self::$singleton = new self;
- }
- return self::$singleton;
- }
-
- /**
- * Return a boolean indicating whether or not the source used for cryptographic
- * random bytes generation in the previously run generate* call
- * was cryptographically strong.
- *
- * @return bool Returns true if the source was strong, false if not.
- */
- public static function wasStrong() {
- return self::singleton()->realWasStrong();
- }
-
- /**
- * Generate a run of (ideally) cryptographically random data and return
- * it in raw binary form.
- * You can use MWCryptRand::wasStrong() if you wish to know if the source used
- * was cryptographically strong.
- *
- * @param int $bytes the number of bytes of random data to generate
- * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
- * strong sources of entropy even if reading from them may steal
- * more entropy from the system than optimal.
- * @return String Raw binary random data
- */
- public static function generate( $bytes, $forceStrong = false ) {
- return self::singleton()->realGenerate( $bytes, $forceStrong );
- }
-
- /**
- * Generate a run of (ideally) cryptographically random data and return
- * it in hexadecimal string format.
- * You can use MWCryptRand::wasStrong() if you wish to know if the source used
- * was cryptographically strong.
- *
- * @param int $chars the number of hex chars of random data to generate
- * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
- * strong sources of entropy even if reading from them may steal
- * more entropy from the system than optimal.
- * @return String Hexadecimal random data
- */
- public static function generateHex( $chars, $forceStrong = false ) {
- return self::singleton()->realGenerateHex( $chars, $forceStrong );
- }
-
-}
$wgVectorUseIconWatch = true;
/**
- * Use VForm design for Special:Userlogin. This can be overridden by
- * a useNew bool in the query string. For instance, if it is globally
- * false, you can try it with useNew=1.
+ * Use compact vertical form ("VForm") design for Special:Userlogin. This can
+ * be overridden by a useNew bool in the query string. For instance, if it is
+ * globally false, you can try it with useNew=1.
+ *
+ * @since 1.22
*/
$wgUseVFormUserLogin = false;
+/**
+ * Use compact vertical form ("VForm") design for account creation
+ * (Special:Userlogin?type=signup).
+ *
+ * @since 1.22
+ */
+$wgUseVFormCreateAccount = false;
+
/**
* Display user edit counts in various prominent places.
*/
*/
class UserBlockedError extends ErrorPageError {
public function __construct( Block $block ) {
- global $wgLang, $wgRequest;
-
- $blocker = $block->getBlocker();
- if ( $blocker instanceof User ) { // local user
- $blockerUserpage = $block->getBlocker()->getUserPage();
- $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]";
- } else { // foreign user
- $link = $blocker;
- }
-
- $reason = $block->mReason;
- if ( $reason == '' ) {
- $reason = wfMessage( 'blockednoreason' )->text();
- }
-
- /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
- * This could be a username, an IP range, or a single IP. */
- $intended = $block->getTarget();
-
- parent::__construct(
- 'blockedtitle',
- $block->mAuto ? 'autoblockedtext' : 'blockedtext',
- array(
- $link,
- $reason,
- $wgRequest->getIP(),
- $block->getByName(),
- $block->getId(),
- $wgLang->formatExpiry( $block->mExpiry ),
- $intended,
- $wgLang->timeanddate( wfTimestamp( TS_MW, $block->mTimestamp ), true )
- )
- );
+ // @todo FIXME: Implement a more proper way to get context here.
+ $params = $block->getPermissionsError( RequestContext::getMain() );
+ parent::__construct( 'blockedtitle', array_shift( $params ), $params );
}
}
* Add a submit button inline in the form (as opposed to
* HTMLForm::addButton(), which will add it at the end).
*/
-class HTMLSubmitField extends HTMLFormField {
+class HTMLSubmitField extends HTMLButtonField {
+ protected $buttonType = 'submit';
+}
+
+/**
+ * Adds a generic button inline to the form. Does not do anything, you must add
+ * click handling code in JavaScript. Use a HTMLSubmitField if you merely
+ * wish to add a submit button to a form.
+ *
+ * @since 1.22
+ */
+class HTMLButtonField extends HTMLFormField {
+ protected $buttonType = 'button';
public function __construct( $info ) {
$info['nodata'] = true;
public function getInputHTML( $value ) {
$attr = array(
'class' => 'mw-htmlform-submit ' . $this->mClass,
- 'name' => $this->mName,
'id' => $this->mID,
);
$attr['disabled'] = 'disabled';
}
- return Xml::submitButton( $value, $attr );
+ return Html::input(
+ $this->mName,
+ $value,
+ $this->buttonType,
+ $attr
+ );
}
protected function needsLabel() {
/** @var Array (location => (start, end)) */
protected $ring = array();
- const RING_SIZE = 16777216; // 2^24
+ const RING_SIZE = 268435456; // 2^28
/**
* @param array $map (location => weight)
public function getLocations( $item, $limit ) {
$locations = array();
$primaryLocation = null;
- $spot = hexdec( substr( sha1( $item ), 0, 6 ) ); // first 24 bits
+ $spot = hexdec( substr( sha1( $item ), 0, 7 ) ); // first 28 bits
foreach ( $this->ring as $location => $range ) {
if ( count( $locations ) >= $limit ) {
break;
--- /dev/null
+<?php
+/**
+ * A cryptographic random generator class used for generating secret keys
+ *
+ * This is based in part on Drupal code as well as what we used in our own code
+ * prior to introduction of this class.
+ *
+ * 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
+ *
+ * @author Daniel Friesen
+ * @file
+ */
+
+class MWCryptRand {
+
+ /**
+ * Minimum number of iterations we want to make in our drift calculations.
+ */
+ const MIN_ITERATIONS = 1000;
+
+ /**
+ * Number of milliseconds we want to spend generating each separate byte
+ * of the final generated bytes.
+ * This is used in combination with the hash length to determine the duration
+ * we should spend doing drift calculations.
+ */
+ const MSEC_PER_BYTE = 0.5;
+
+ /**
+ * Singleton instance for public use
+ */
+ protected static $singleton = null;
+
+ /**
+ * The hash algorithm being used
+ */
+ protected $algo = null;
+
+ /**
+ * The number of bytes outputted by the hash algorithm
+ */
+ protected $hashLength = null;
+
+ /**
+ * A boolean indicating whether the previous random generation was done using
+ * cryptographically strong random number generator or not.
+ */
+ protected $strong = null;
+
+ /**
+ * Initialize an initial random state based off of whatever we can find
+ */
+ protected function initialRandomState() {
+ // $_SERVER contains a variety of unstable user and system specific information
+ // It'll vary a little with each page, and vary even more with separate users
+ // It'll also vary slightly across different machines
+ $state = serialize( $_SERVER );
+
+ // To try vary the system information of the state a bit more
+ // by including the system's hostname into the state
+ $state .= wfHostname();
+
+ // Try to gather a little entropy from the different php rand sources
+ $state .= rand() . uniqid( mt_rand(), true );
+
+ // Include some information about the filesystem's current state in the random state
+ $files = array();
+
+ // We know this file is here so grab some info about ourselves
+ $files[] = __FILE__;
+
+ // We must also have a parent folder, and with the usual file structure, a grandparent
+ $files[] = __DIR__;
+ $files[] = dirname( __DIR__ );
+
+ // The config file is likely the most often edited file we know should be around
+ // so include its stat info into the state.
+ // The constant with its location will almost always be defined, as WebStart.php defines
+ // MW_CONFIG_FILE to $IP/LocalSettings.php unless being configured with MW_CONFIG_CALLBACK (eg. the installer)
+ if ( defined( 'MW_CONFIG_FILE' ) ) {
+ $files[] = MW_CONFIG_FILE;
+ }
+
+ foreach ( $files as $file ) {
+ wfSuppressWarnings();
+ $stat = stat( $file );
+ wfRestoreWarnings();
+ if ( $stat ) {
+ // stat() duplicates data into numeric and string keys so kill off all the numeric ones
+ foreach ( $stat as $k => $v ) {
+ if ( is_numeric( $k ) ) {
+ unset( $k );
+ }
+ }
+ // The absolute filename itself will differ from install to install so don't leave it out
+ if ( ( $path = realpath( $file ) ) !== false ) {
+ $state .= $path;
+ } else {
+ $state .= $file;
+ }
+ $state .= implode( '', $stat );
+ } else {
+ // The fact that the file isn't there is worth at least a
+ // minuscule amount of entropy.
+ $state .= '0';
+ }
+ }
+
+ // Try and make this a little more unstable by including the varying process
+ // id of the php process we are running inside of if we are able to access it
+ if ( function_exists( 'getmypid' ) ) {
+ $state .= getmypid();
+ }
+
+ // If available try to increase the instability of the data by throwing in
+ // the precise amount of memory that we happen to be using at the moment.
+ if ( function_exists( 'memory_get_usage' ) ) {
+ $state .= memory_get_usage( true );
+ }
+
+ // It's mostly worthless but throw the wiki's id into the data for a little more variance
+ $state .= wfWikiID();
+
+ // If we have a secret key or proxy key set then throw it into the state as well
+ global $wgSecretKey, $wgProxyKey;
+ if ( $wgSecretKey ) {
+ $state .= $wgSecretKey;
+ } elseif ( $wgProxyKey ) {
+ $state .= $wgProxyKey;
+ }
+
+ return $state;
+ }
+
+ /**
+ * Randomly hash data while mixing in clock drift data for randomness
+ *
+ * @param string $data The data to randomly hash.
+ * @return String The hashed bytes
+ * @author Tim Starling
+ */
+ protected function driftHash( $data ) {
+ // Minimum number of iterations (to avoid slow operations causing the loop to gather little entropy)
+ $minIterations = self::MIN_ITERATIONS;
+ // Duration of time to spend doing calculations (in seconds)
+ $duration = ( self::MSEC_PER_BYTE / 1000 ) * $this->hashLength();
+ // Create a buffer to use to trigger memory operations
+ $bufLength = 10000000;
+ $buffer = str_repeat( ' ', $bufLength );
+ $bufPos = 0;
+
+ // Iterate for $duration seconds or at least $minIterations number of iterations
+ $iterations = 0;
+ $startTime = microtime( true );
+ $currentTime = $startTime;
+ while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
+ // Trigger some memory writing to trigger some bus activity
+ // This may create variance in the time between iterations
+ $bufPos = ( $bufPos + 13 ) % $bufLength;
+ $buffer[$bufPos] = ' ';
+ // Add the drift between this iteration and the last in as entropy
+ $nextTime = microtime( true );
+ $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
+ $data .= $delta;
+ // Every 100 iterations hash the data and entropy
+ if ( $iterations % 100 === 0 ) {
+ $data = sha1( $data );
+ }
+ $currentTime = $nextTime;
+ $iterations++;
+ }
+ $timeTaken = $currentTime - $startTime;
+ $data = $this->hash( $data );
+
+ wfDebug( __METHOD__ . ": Clock drift calculation " .
+ "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
+ "iterations=$iterations, " .
+ "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)\n" );
+ return $data;
+ }
+
+ /**
+ * Return a rolling random state initially build using data from unstable sources
+ * @return string A new weak random state
+ */
+ protected function randomState() {
+ static $state = null;
+ if ( is_null( $state ) ) {
+ // Initialize the state with whatever unstable data we can find
+ // It's important that this data is hashed right afterwards to prevent
+ // it from being leaked into the output stream
+ $state = $this->hash( $this->initialRandomState() );
+ }
+ // Generate a new random state based on the initial random state or previous
+ // random state by combining it with clock drift
+ $state = $this->driftHash( $state );
+ return $state;
+ }
+
+ /**
+ * Decide on the best acceptable hash algorithm we have available for hash()
+ * @throws MWException
+ * @return String A hash algorithm
+ */
+ protected function hashAlgo() {
+ if ( !is_null( $this->algo ) ) {
+ return $this->algo;
+ }
+
+ $algos = hash_algos();
+ $preference = array( 'whirlpool', 'sha256', 'sha1', 'md5' );
+
+ foreach ( $preference as $algorithm ) {
+ if ( in_array( $algorithm, $algos ) ) {
+ $this->algo = $algorithm;
+ wfDebug( __METHOD__ . ": Using the {$this->algo} hash algorithm.\n" );
+ return $this->algo;
+ }
+ }
+
+ // We only reach here if no acceptable hash is found in the list, this should
+ // be a technical impossibility since most of php's hash list is fixed and
+ // some of the ones we list are available as their own native functions
+ // But since we already require at least 5.2 and hash() was default in
+ // 5.1.2 we don't bother falling back to methods like sha1 and md5.
+ throw new MWException( "Could not find an acceptable hashing function in hash_algos()" );
+ }
+
+ /**
+ * Return the byte-length output of the hash algorithm we are
+ * using in self::hash and self::hmac.
+ *
+ * @return int Number of bytes the hash outputs
+ */
+ protected function hashLength() {
+ if ( is_null( $this->hashLength ) ) {
+ $this->hashLength = strlen( $this->hash( '' ) );
+ }
+ return $this->hashLength;
+ }
+
+ /**
+ * Generate an acceptably unstable one-way-hash of some text
+ * making use of the best hash algorithm that we have available.
+ *
+ * @param $data string
+ * @return String A raw hash of the data
+ */
+ protected function hash( $data ) {
+ return hash( $this->hashAlgo(), $data, true );
+ }
+
+ /**
+ * Generate an acceptably unstable one-way-hmac of some text
+ * making use of the best hash algorithm that we have available.
+ *
+ * @param $data string
+ * @param $key string
+ * @return String A raw hash of the data
+ */
+ protected function hmac( $data, $key ) {
+ return hash_hmac( $this->hashAlgo(), $data, $key, true );
+ }
+
+ /**
+ * @see self::wasStrong()
+ */
+ public function realWasStrong() {
+ if ( is_null( $this->strong ) ) {
+ throw new MWException( __METHOD__ . ' called before generation of random data' );
+ }
+ return $this->strong;
+ }
+
+ /**
+ * @see self::generate()
+ */
+ public function realGenerate( $bytes, $forceStrong = false ) {
+ wfProfileIn( __METHOD__ );
+
+ wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " . wfGetAllCallers( 5 ) . "\n" );
+
+ $bytes = floor( $bytes );
+ static $buffer = '';
+ if ( is_null( $this->strong ) ) {
+ // Set strength to false initially until we know what source data is coming from
+ $this->strong = true;
+ }
+
+ if ( strlen( $buffer ) < $bytes ) {
+ // If available make use of mcrypt_create_iv URANDOM source to generate randomness
+ // On unix-like systems this reads from /dev/urandom but does it without any buffering
+ // and bypasses openbasedir restrictions, so it's preferable to reading directly
+ // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
+ // entropy so this is also preferable to just trying to read urandom because it may work
+ // on Windows systems as well.
+ if ( function_exists( 'mcrypt_create_iv' ) ) {
+ wfProfileIn( __METHOD__ . '-mcrypt' );
+ $rem = $bytes - strlen( $buffer );
+ $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
+ if ( $iv === false ) {
+ wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" );
+ } else {
+ $buffer .= $iv;
+ wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) . " bytes of randomness.\n" );
+ }
+ wfProfileOut( __METHOD__ . '-mcrypt' );
+ }
+ }
+
+ if ( strlen( $buffer ) < $bytes ) {
+ // If available make use of openssl's random_pseudo_bytes method to attempt to generate randomness.
+ // However don't do this on Windows with PHP < 5.3.4 due to a bug:
+ // http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php
+ // http://git.php.net/?p=php-src.git;a=commitdiff;h=cd62a70863c261b07f6dadedad9464f7e213cad5
+ if ( function_exists( 'openssl_random_pseudo_bytes' )
+ && ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) )
+ ) {
+ wfProfileIn( __METHOD__ . '-openssl' );
+ $rem = $bytes - strlen( $buffer );
+ $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
+ if ( $openssl_bytes === false ) {
+ wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" );
+ } else {
+ $buffer .= $openssl_bytes;
+ wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " . strlen( $openssl_bytes ) . " bytes of " . ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
+ }
+ if ( strlen( $buffer ) >= $bytes ) {
+ // openssl tells us if the random source was strong, if some of our data was generated
+ // using it use it's say on whether the randomness is strong
+ $this->strong = !!$openssl_strong;
+ }
+ wfProfileOut( __METHOD__ . '-openssl' );
+ }
+ }
+
+ // Only read from urandom if we can control the buffer size or were passed forceStrong
+ if ( strlen( $buffer ) < $bytes && ( function_exists( 'stream_set_read_buffer' ) || $forceStrong ) ) {
+ wfProfileIn( __METHOD__ . '-fopen-urandom' );
+ $rem = $bytes - strlen( $buffer );
+ if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
+ wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom without control over the buffer size.\n" );
+ }
+ // /dev/urandom is generally considered the best possible commonly
+ // available random source, and is available on most *nix systems.
+ wfSuppressWarnings();
+ $urandom = fopen( "/dev/urandom", "rb" );
+ wfRestoreWarnings();
+
+ // Attempt to read all our random data from urandom
+ // php's fread always does buffered reads based on the stream's chunk_size
+ // so in reality it will usually read more than the amount of data we're
+ // asked for and not storing that risks depleting the system's random pool.
+ // If stream_set_read_buffer is available set the chunk_size to the amount
+ // of data we need. Otherwise read 8k, php's default chunk_size.
+ if ( $urandom ) {
+ // php's default chunk_size is 8k
+ $chunk_size = 1024 * 8;
+ if ( function_exists( 'stream_set_read_buffer' ) ) {
+ // If possible set the chunk_size to the amount of data we need
+ stream_set_read_buffer( $urandom, $rem );
+ $chunk_size = $rem;
+ }
+ $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
+ $buffer .= $random_bytes;
+ fclose( $urandom );
+ wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) . " bytes of randomness.\n" );
+ if ( strlen( $buffer ) >= $bytes ) {
+ // urandom is always strong, set to true if all our data was generated using it
+ $this->strong = true;
+ }
+ } else {
+ wfDebug( __METHOD__ . ": /dev/urandom could not be opened.\n" );
+ }
+ wfProfileOut( __METHOD__ . '-fopen-urandom' );
+ }
+
+ // If we cannot use or generate enough data from a secure source
+ // use this loop to generate a good set of pseudo random data.
+ // This works by initializing a random state using a pile of unstable data
+ // and continually shoving it through a hash along with a variable salt.
+ // We hash the random state with more salt to avoid the state from leaking
+ // out and being used to predict the /randomness/ that follows.
+ if ( strlen( $buffer ) < $bytes ) {
+ wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" );
+ }
+ while ( strlen( $buffer ) < $bytes ) {
+ wfProfileIn( __METHOD__ . '-fallback' );
+ $buffer .= $this->hmac( $this->randomState(), mt_rand() );
+ // This code is never really cryptographically strong, if we use it
+ // at all, then set strong to false.
+ $this->strong = false;
+ wfProfileOut( __METHOD__ . '-fallback' );
+ }
+
+ // Once the buffer has been filled up with enough random data to fulfill
+ // the request shift off enough data to handle the request and leave the
+ // unused portion left inside the buffer for the next request for random data
+ $generated = substr( $buffer, 0, $bytes );
+ $buffer = substr( $buffer, $bytes );
+
+ wfDebug( __METHOD__ . ": " . strlen( $buffer ) . " bytes of randomness leftover in the buffer.\n" );
+
+ wfProfileOut( __METHOD__ );
+ return $generated;
+ }
+
+ /**
+ * @see self::generateHex()
+ */
+ public function realGenerateHex( $chars, $forceStrong = false ) {
+ // hex strings are 2x the length of raw binary so we divide the length in half
+ // odd numbers will result in a .5 that leads the generate() being 1 character
+ // short, so we use ceil() to ensure that we always have enough bytes
+ $bytes = ceil( $chars / 2 );
+ // Generate the data and then convert it to a hex string
+ $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
+ // A bit of paranoia here, the caller asked for a specific length of string
+ // here, and it's possible (eg when given an odd number) that we may actually
+ // have at least 1 char more than they asked for. Just in case they made this
+ // call intending to insert it into a database that does truncation we don't
+ // want to give them too much and end up with their database and their live
+ // code having two different values because part of what we gave them is truncated
+ // hence, we strip out any run of characters longer than what we were asked for.
+ return substr( $hex, 0, $chars );
+ }
+
+ /** Publicly exposed static methods **/
+
+ /**
+ * Return a singleton instance of MWCryptRand
+ * @return MWCryptRand
+ */
+ protected static function singleton() {
+ if ( is_null( self::$singleton ) ) {
+ self::$singleton = new self;
+ }
+ return self::$singleton;
+ }
+
+ /**
+ * Return a boolean indicating whether or not the source used for cryptographic
+ * random bytes generation in the previously run generate* call
+ * was cryptographically strong.
+ *
+ * @return bool Returns true if the source was strong, false if not.
+ */
+ public static function wasStrong() {
+ return self::singleton()->realWasStrong();
+ }
+
+ /**
+ * Generate a run of (ideally) cryptographically random data and return
+ * it in raw binary form.
+ * You can use MWCryptRand::wasStrong() if you wish to know if the source used
+ * was cryptographically strong.
+ *
+ * @param int $bytes the number of bytes of random data to generate
+ * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
+ * strong sources of entropy even if reading from them may steal
+ * more entropy from the system than optimal.
+ * @return String Raw binary random data
+ */
+ public static function generate( $bytes, $forceStrong = false ) {
+ return self::singleton()->realGenerate( $bytes, $forceStrong );
+ }
+
+ /**
+ * Generate a run of (ideally) cryptographically random data and return
+ * it in hexadecimal string format.
+ * You can use MWCryptRand::wasStrong() if you wish to know if the source used
+ * was cryptographically strong.
+ *
+ * @param int $chars the number of hex chars of random data to generate
+ * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
+ * strong sources of entropy even if reading from them may steal
+ * more entropy from the system than optimal.
+ * @return String Hexadecimal random data
+ */
+ public static function generateHex( $chars, $forceStrong = false ) {
+ return self::singleton()->realGenerateHex( $chars, $forceStrong );
+ }
+
+}
'numberofactiveusers',
'numberofpages',
'currentversion',
+ 'rootpagename',
+ 'rootpagenamee',
'basepagename',
'basepagenamee',
'currenttimestamp',
$m = null;
if ( $wgMimeDetectorCommand ) {
- // @todo FIXME: Use wfShellExec
- $fn = wfEscapeShellArg( $file );
- $m = `$wgMimeDetectorCommand $fn`;
+ $args = wfEscapeShellArg( $file );
+ $m = wfShellExec( "$wgMimeDetectorCommand $args" );
} elseif ( function_exists( "finfo_open" ) && function_exists( "finfo_file" ) ) {
# This required the fileinfo extension by PECL,
}
/**
- * Get the result of the work (whatever it is), or false.
+ * Get the result of the work (whatever it is), or the result of the error() function.
+ * This returns the result of the first applicable method that returns a non-false value,
+ * where the methods are checked in the following order:
+ * - a) doWork() : Applies if the work is exclusive or no another process
+ * is doing it, and on the condition that either this process
+ * successfully entered the pool or the pool counter is down.
+ * - b) doCachedWork() : Applies if the work is cacheable and this blocked on another
+ * process which finished the work.
+ * - c) fallback() : Applies for all remaining cases.
+ * If these all fall through (by returning false), then the result of error() is returned.
+ *
* @param $skipcache bool
- * @return bool|mixed
+ * @return mixed
*/
public function execute( $skipcache = false ) {
if ( $this->cacheable && !$skipcache ) {
*
* @file
* @ingroup StatCounter
+ * @author Aaron Schulz
*/
/**
$this->deltas = array();
}
+ /**
+ * @param array $deltas
+ * @return void
+ */
protected function sendDeltasUDP( array $deltas ) {
global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgAggregateStatsID;
}
}
+ /**
+ * @param array $deltas
+ * @return void
+ */
protected function sendDeltasMemc( array $deltas ) {
global $wgMemc;
* @return DateInterval Offset that was applied to the timestamp
*/
public function offsetForUser( User $user ) {
- global $wgLocalTZOffset;
+ global $wgLocalTZoffset;
$option = $user->getOption( 'timecorrection' );
$data = explode( '|', $option, 3 );
// first value.
if ( $data[0] == 'System' ) {
// First value is System, so use the system offset.
- if ( isset( $wgLocalTZOffset ) ) {
- $diff = $wgLocalTZOffset;
+ if ( isset( $wgLocalTZoffset ) ) {
+ $diff = $wgLocalTZoffset;
}
} elseif ( $data[0] == 'Offset' ) {
// First value is Offset, so use the specified offset
return $errors;
}
- global $wgContLang, $wgLang, $wgEmailConfirmToEdit;
+ global $wgEmailConfirmToEdit;
if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) {
$errors[] = array( 'confirmedittext' );
// Don't block the user from editing their own talk page unless they've been
// explicitly blocked from that too.
} elseif ( $user->isBlocked() && $user->mBlock->prevents( $action ) !== false ) {
- $block = $user->getBlock();
-
- // This is from OutputPage::blockedPage
- // Copied at r23888 by werdna
-
- $id = $user->blockedBy();
- $reason = $user->blockedFor();
- if ( $reason == '' ) {
- $reason = wfMessage( 'blockednoreason' )->text();
- }
- $ip = $user->getRequest()->getIP();
-
- if ( is_numeric( $id ) ) {
- $name = User::whoIs( $id );
- } else {
- $name = $id;
- }
-
- $link = '[[' . $wgContLang->getNsText( NS_USER ) . ":{$name}|{$name}]]";
- $blockid = $block->getId();
- $blockExpiry = $block->getExpiry();
- $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $block->mTimestamp ), true );
- if ( $blockExpiry == 'infinity' ) {
- $blockExpiry = wfMessage( 'infiniteblock' )->text();
- } else {
- $blockExpiry = $wgLang->timeanddate( wfTimestamp( TS_MW, $blockExpiry ), true );
- }
-
- $intended = strval( $block->getTarget() );
-
- $errors[] = array( ( $block->mAuto ? 'autoblockedtext' : 'blockedtext' ), $link, $reason, $ip, $name,
- $blockid, $blockExpiry, $intended, $blockTimestamp );
+ // @todo FIXME: Pass the relevant context into this function.
+ $errors[] = $user->getBlock()->getPermissionsError( RequestContext::getMain() );
}
return $errors;
}
$this->loadGroups();
$this->mGroups[] = $group;
+ // In case loadGroups was not called before, we now have the right twice.
+ // Get rid of the duplicate.
+ $this->mGroups = array_unique( $this->mGroups );
$this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) );
$this->invalidateCache();
protected function feedItem( $row ) {
$title = Title::makeTitle( intval( $row->page_namespace ), $row->page_title );
- if ( $title ) {
+ if( $title && $title->userCan( 'read' ) ) {
$date = $row->rev_timestamp;
$comments = $title->getTalkPage()->getFullURL();
$revision = Revision::newFromRow( $row );
$this->feedItemAuthor( $revision ),
$comments
);
- } else {
- return null;
}
+ return null;
}
/**
$this->addFieldsIf( 'rev_comment', $this->fld_comment || $this->fld_parsedcomment );
$this->addFieldsIf( 'rev_len', $this->fld_size || $this->fld_sizediff );
$this->addFieldsIf( 'rev_minor_edit', $this->fld_flags );
- $this->addFieldsIf( 'rev_parent_id', $this->fld_flags || $this->fld_sizediff );
+ $this->addFieldsIf( 'rev_parent_id', $this->fld_flags || $this->fld_sizediff || $this->fld_ids );
$this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
if ( $this->fld_tags ) {
$vals['pageid'] = intval( $row->rev_page );
$vals['revid'] = intval( $row->rev_id );
// $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
+
+ if ( !is_null( $row->rev_parent_id ) ) {
+ $vals['parentid'] = intval( $row->rev_parent_id );
+ }
}
$title = Title::makeTitle( $row->page_namespace, $row->page_title );
),
'ids' => array(
'pageid' => 'integer',
- 'revid' => 'integer'
+ 'revid' => 'integer',
+ 'parentid' => array(
+ ApiBase::PROP_TYPE => 'integer',
+ ApiBase::PROP_NULLABLE => true
+ )
),
'title' => array(
'ns' => 'namespace',
/**
* Run an anonymous function as soon as there is no transaction pending.
* If there is a transaction and it is rolled back, then the callback is cancelled.
+ * Queries in the function will run in AUTO-COMMIT mode unless there are begin() calls.
* Callbacks must commit any transactions that they begin.
*
* This is useful for updates to different systems or when separate transactions are needed.
}
/**
- * @return bool
+ * @return bool Whether to cache in RepoGroup (this avoids OOMs)
*/
function isCacheable() {
- $this->load();
- return strlen( $this->metadata ) <= self::CACHE_FIELD_MAX_LEN; // avoid OOMs
+ $this->load(); // if loaded from cache, metadata will be null if it didn't fit
+ return $this->metadata !== null && strlen( $this->metadata ) <= self::CACHE_FIELD_MAX_LEN;
}
/**
/**
* Environment check for setting the preferred PHP file extension.
+ * @return bool
*/
protected function envCheckExtension() {
// @todo FIXME: Detect this properly
}
/**
- * TODO: document
+ * Environment check for preferred locale in shell
* @return bool
*/
protected function envCheckShellLocale() {
}
/**
- * TODO: document
+ * Environment check for the permissions of the uploads directory
* @return bool
*/
protected function envCheckUploadsDirectory() {
$title = Title::makeTitleSafe( $row->job_namespace, $row->job_title );
if ( !$title ) {
$dbw->delete( 'job', array( 'job_id' => $row->job_id ), __METHOD__ );
- wfDebugLog( 'JobQueueDB', "Row has invalid title '{$row->job_title}'." );
+ wfDebug( "Row has invalid title '{$row->job_title}'." );
continue; // try again
}
$job = Job::factory( $row->job_cmd, $title,
array( 'job_cmd' => $this->type, 'job_token' => $uuid ), __METHOD__
);
if ( !$row ) { // raced out by duplicate job removal
- wfDebugLog( 'JobQueueDB', "Row deleted as duplicate by another process." );
+ wfDebug( "Row deleted as duplicate by another process." );
}
} else {
break; // nothing to do
*/
private function getCacheKey( $property ) {
list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
- return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, $property );
+ $cluster = is_string( $this->cluster ) ? $this->cluster : 'main';
+ return wfForeignMemcKey( $db, $prefix, 'jobqueue', $cluster, $this->type, $property );
}
/**
$partitionRing = new HashRing( $partitionsTry );
// Because jobs are spread across partitions, per-job de-duplication needs
// to use a consistent hash to avoid allowing duplicate jobs per partition.
- // When inserting a batch of de-duplicated jobs, QoS_Atomic is disregarded.
+ // When inserting a batch of de-duplicated jobs, QOS_ATOMIC is disregarded.
$uJobsByPartition = array(); // (partition name => job list)
foreach ( $jobs as $key => $job ) {
if ( $job->ignoreDuplicates() ) {
}
}
// Get the batches of jobs that are not de-duplicated
- if ( $flags & self::QoS_Atomic ) {
+ if ( $flags & self::QOS_ATOMIC ) {
$nuJobBatches = array( $jobs ); // all or nothing
} else {
// Split the jobs into batches and spread them out over servers if there
$conn->setex( $key, $expiry, $value );
}
- $result = $conn->exec();
+ /*
+ * multi()/exec() (transactional mode) allows multiple values to
+ * be set/get at once and will return an array of results, in
+ * the order they were set/get. In this case, we only set 1
+ * value, which should (in case of success) result in true.
+ */
+ $result = ( $conn->exec() == array( true ) );
} catch ( RedisException $e ) {
$result = false;
$this->handleException( $server, $conn, $e );
$parser->setFunctionHook( 'pagenamee', array( __CLASS__, 'pagenamee' ), SFH_NO_HASH );
$parser->setFunctionHook( 'fullpagename', array( __CLASS__, 'fullpagename' ), SFH_NO_HASH );
$parser->setFunctionHook( 'fullpagenamee', array( __CLASS__, 'fullpagenamee' ), SFH_NO_HASH );
+ $parser->setFunctionHook( 'rootpagename', array( __CLASS__, 'rootpagename' ), SFH_NO_HASH );
+ $parser->setFunctionHook( 'rootpagenamee', array( __CLASS__, 'rootpagenamee' ), SFH_NO_HASH );
$parser->setFunctionHook( 'basepagename', array( __CLASS__, 'basepagename' ), SFH_NO_HASH );
$parser->setFunctionHook( 'basepagenamee', array( __CLASS__, 'basepagenamee' ), SFH_NO_HASH );
$parser->setFunctionHook( 'subpagename', array( __CLASS__, 'subpagename' ), SFH_NO_HASH );
}
return wfEscapeWikiText( $t->getSubpageUrlForm() );
}
+ static function rootpagename( $parser, $title = null ) {
+ $t = Title::newFromText( $title );
+ if ( is_null( $t ) ) {
+ return '';
+ }
+ return wfEscapeWikiText( $t->getRootText() );
+ }
+ static function rootpagenamee( $parser, $title = null ) {
+ $t = Title::newFromText( $title );
+ if ( is_null( $t ) ) {
+ return '';
+ }
+ return wfEscapeWikiText( wfUrlEncode( str_replace( ' ', '_', $t->getRootText() ) ) );
+ }
static function basepagename( $parser, $title = null ) {
$t = Title::newFromText( $title );
if ( is_null( $t ) ) {
case 'subpagenamee':
$value = wfEscapeWikiText( $this->mTitle->getSubpageUrlForm() );
break;
+ case 'rootpagename':
+ $value = wfEscapeWikiText( $this->mTitle->getRootText() );
+ break;
+ case 'rootpagenamee':
+ $value = wfEscapeWikiText( wfUrlEncode( str_replace( ' ', '_', $this->mTitle->getRootText() ) ) );
+ break;
case 'basepagename':
$value = wfEscapeWikiText( $this->mTitle->getBaseText() );
break;
wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" );
}
}
- }
- if ( $xml === false ) {
- if ( $cacheable ) {
+ if ( $xml === false ) {
wfProfileIn( __METHOD__ . '-cache-miss' );
$xml = $this->preprocessToXml( $text, $flags );
$cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $xml;
$wgMemc->set( $cacheKey, $cacheValue, 86400 );
wfProfileOut( __METHOD__ . '-cache-miss' );
wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" );
- } else {
- $xml = $this->preprocessToXml( $text, $flags );
}
-
+ } else {
+ $xml = $this->preprocessToXml( $text, $flags );
}
+
// Fail if the number of elements exceeds acceptable limits
// Do not attempt to generate the DOM
$this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
}
if ( !isset( $this->opts['year'] ) ) {
- $this->opts['year'] = '';
+ $this->opts['year'] = gmdate( 'Y' );
}
if ( !isset( $this->opts['month'] ) ) {
* @return Boolean
*/
private function shouldShowVForm() {
- global $wgUseVFormUserLogin;
+ global $wgUseVFormCreateAccount, $wgUseVFormUserLogin;
if ( $this->mType == 'signup' ) {
- return false;
+ return $this->mRequest->getBool( 'useNew', $wgUseVFormCreateAccount );
} else {
return $this->mRequest->getBool( 'useNew', $wgUseVFormUserLogin );
}
}
if ( $this->mType == 'signup' ) {
- $template = new UsercreateTemplate();
+ $out->addModules( 'mediawiki.special.userlogin.signup' );
+ if ( $this->mShowVForm ) {
+ $template = new UsercreateTemplateVForm();
+ $out->addModuleStyles( array(
+ 'mediawiki.ui',
+ 'mediawiki.special.createaccount.vform'
+ ) );
+ // XXX hack pending RL or JS parse() support for complex content messages
+ // https://bugzilla.wikimedia.org/show_bug.cgi?id=25349
+ $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp',
+ $this->msg( 'createacct-imgcaptcha-help' )->parse() );
+ $out->addModules( 'mediawiki.special.createaccount.vform.js' );
+ } else {
+ $template = new UsercreateTemplate();
+ }
$q = 'action=submitlogin&type=signup';
$linkq = 'type=login';
$linkmsg = 'gotaccount';
- $out->addModules( 'mediawiki.special.userlogin.signup' );
} else {
if ( $this->mShowVForm ) {
$template = new UserloginTemplateVForm();
--- /dev/null
+<?php
+/**
+ * Html form for account creation with new VForm appearance.
+ *
+ * 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 Templates
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ die( -1 );
+}
+
+/**
+ * Html form for create account with new VForm appearance.
+ *
+ * @since 1.22
+ */
+class UsercreateTemplateVForm extends BaseTemplate {
+
+ /**
+ * Extensions (AntiSpoof and TitleBlacklist) call this in response to
+ * UserCreateForm hook to add checkboxes to the create account form.
+ */
+ function addInputItem( $name, $value, $type, $msg, $helptext = false ) {
+ $this->data['extraInput'][] = array(
+ 'name' => $name,
+ 'value' => $value,
+ 'type' => $type,
+ 'msg' => $msg,
+ 'helptext' => $helptext,
+ );
+ }
+
+ function execute() {
+ global $wgCookieExpiration;
+ $expirationDays = ceil( $wgCookieExpiration / ( 3600 * 24 ) );
+?>
+<div class="mw-ui-container">
+ <?php
+ if ( $this->haveData( 'languages' ) ) {
+ ?>
+ <div id="languagelinks">
+ <p><?php $this->html( 'languages' ); ?></p>
+ </div>
+ <?php
+ }
+ ?>
+<div id="userloginForm">
+<h2 class="createaccount-join"><?php $this->msg( 'createacct-join' ); ?></h2>
+<form name="userlogin2" id="userlogin2" class="mw-ui-vform" method="post" action="<?php $this->text( 'action' ); ?>">
+ <section class="mw-form-header">
+ <?php $this->html( 'header' ); /* extensions such as ConfirmEdit add form HTML here */ ?>
+ </section>
+ <?php
+ if ( $this->data['message'] ) {
+?>
+ <div class="<?php $this->text( 'messagetype' ); ?>box">
+ <?php if ( $this->data['messagetype'] == 'error' ) { ?>
+ <strong><?php $this->msg( 'loginerror' )?></strong><br />
+ <?php } ?>
+ <?php $this->html( 'message' ); ?>
+ </div>
+ <?php } ?>
+ <div>
+ <label for='wpName2'>
+ <?php $this->msg( 'userlogin-yourname' ); ?>
+
+ <span class="mw-ui-flush-right"><?php echo $this->getMsg( 'createacct-helpusername-link' )->parse(); ?></span>
+ </label>
+ <?php echo Html::input( 'wpName', $this->data['name'], 'text', array(
+ 'class' => 'mw-input loginText',
+ 'id' => 'wpName2',
+ 'tabindex' => '1',
+ 'size' => '20',
+ 'required',
+ 'placeholder' => $this->getMsg( 'userlogin-yourname-ph' )->text(),
+ 'autofocus'
+ ) ); ?>
+ </div>
+ <div>
+ <?php if ( $this->data['createemail'] ) { ?>
+ <label class="mw-ui-checkbox-label">
+ <input name="wpCreateaccountMail" type="checkbox" value="1" id="wpCreateaccountMail" tabindex="2"
+ <?php if ( $this->data['createemailset'] ) {
+ echo 'checked="checked"';
+ } ?>
+ >
+ <?php $this->msg( 'createaccountmail' ); ?>
+ </label>
+ <?php } ?>
+ </div>
+ <div class="mw-row-password">
+ <label for='wpPassword2'><?php $this->msg( 'userlogin-yourpassword' ); ?></label>
+ <?php echo Html::input( 'wpPassword', null, 'password', array(
+ 'class' => 'mw-input loginPassword',
+ 'id' => 'wpPassword2',
+ 'tabindex' => '3',
+ 'size' => '20',
+ 'required',
+ 'placeholder' => $this->getMsg( 'createacct-yourpassword-ph' )->text()
+ ) + User::passwordChangeInputAttribs() ); ?>
+ </div>
+ <?php if ( $this->data['usedomain'] ) {
+ $doms = "";
+ foreach ( $this->data['domainnames'] as $dom ) {
+ $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+ }
+ ?>
+ <div>
+ <label><?php $this->msg( 'yourdomainname' ); ?></label>
+ <div class="mw-input">
+ <select name="wpDomain" value="<?php $this->text( 'domain' ); ?>"
+ tabindex="4">
+ <?php echo $doms ?>
+ </select>
+ </div>
+ </div>
+ <?php } ?>
+ <div class="mw-row-password">
+ <label for='wpRetype'><?php $this->msg( 'createacct-yourpasswordagain' ); ?></label>
+ <?php
+ echo Html::input( 'wpRetype', null, 'password', array(
+ 'class' => 'mw-input loginPassword',
+ 'id' => 'wpRetype',
+ 'tabindex' => '5',
+ 'size' => '20',
+ 'required',
+ 'placeholder' => $this->getMsg( 'createacct-yourpasswordagain-ph' )->text()
+ ) + User::passwordChangeInputAttribs() );
+ ?>
+ </div>
+ <div>
+ <?php if ( $this->data['useemail'] ) { ?>
+ <label for='wpEmail'>
+ <?php
+ $this->msg( $this->data['emailrequired'] ?
+ 'createacct-emailrequired' :
+ 'createacct-emailoptional'
+ );
+ ?>
+ </label>
+ <?php
+ echo Html::input( 'wpEmail', $this->data['email'], 'email', array(
+ 'class' => 'mw-input loginText',
+ 'id' => 'wpEmail',
+ 'tabindex' => '6',
+ 'size' => '20',
+ 'placeholder' => $this->getMsg( 'createacct-email-ph' )->text()
+ ) + ( $this->data['emailrequired'] ? array() : array( 'required' => '' ) ) );
+ ?>
+ <?php
+ // VForm eliminates the prefsectiontip div tip:
+ // prefs-help-email-required is redundant with the placeholder text
+ // Doesn't show the wordy prefs-help-email
+ // Doesn't show the wordy prefs-help-email-others
+ ?>
+ <?php } ?>
+ </div>
+ <?php if ( $this->data['userealname'] ) { ?>
+ <div>
+ <label for='wpRealName'><?php $this->msg( 'createacct-realname' ); ?></label>
+ <input type='text' class='mw-input loginText' name="wpRealName" id="wpRealName"
+ tabindex="7"
+ value="<?php $this->text( 'realname' ); ?>" size='20' />
+ <div class="prefsectiontip">
+ <?php $this->msgWiki( 'prefs-help-realname' ); ?>
+ </div>
+ </div>
+ <?php }
+ if ( $this->data['usereason'] ) { ?>
+ <div>
+ <label for='wpReason'><?php $this->msg( 'createacct-reason' ); ?></label>
+ <input type='text' class='mw-input loginText' name="wpReason" id="wpReason"
+ tabindex="8"
+ value="<?php $this->text( 'reason' ); ?>" size='20' />
+ </div>
+ <?php }
+ $tabIndex = 9;
+ if ( isset( $this->data['extraInput'] ) && is_array( $this->data['extraInput'] ) ) {
+ foreach ( $this->data['extraInput'] as $inputItem ) { ?>
+ <div>
+ <?php
+ // If it's a checkbox, output the whole thing (assume it has a msg).
+ if ( $inputItem['type'] == 'checkbox' ) {
+ ?>
+ <label class="mw-ui-checkbox-label">
+ <input
+ name="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+ id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+ type="checkbox" value="1"
+ tabindex="<?php echo $tabIndex++; ?>"
+ <?php if ( !empty( $inputItem['value'] ) ) {
+ echo 'checked="checked"';
+ } ?>
+ >
+ <?php $this->msg( $inputItem['msg'] ); ?>
+ </label>
+ <?php
+ } else {
+ // Not a checkbox.
+ if ( !empty( $inputItem['msg'] ) ) {
+ // Output the message label
+ ?>
+ <label for="<?php echo htmlspecialchars( $inputItem['name'] ); ?>">
+ <?php $this->msgWiki( $inputItem['msg'] ); ?>
+ </label>
+ <?php
+ }
+ ?>
+ <input
+ type="<?php echo htmlspecialchars( $inputItem['type'] ); ?>"
+ class="mw-input"
+ name="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+ tabindex="<?php echo $tabIndex++; ?>"
+ value="<?php echo htmlspecialchars( $inputItem['value'] ); ?>"
+ id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+ />
+ <?php
+ }
+ if ( $inputItem['helptext'] !== false ) {
+ ?>
+ <div class="prefsectiontip">
+ <?php $this->msgWiki( $inputItem['helptext'] ); ?>
+ </div>
+ <?php
+ }
+ ?>
+ </div>
+ <?php
+ }
+ }
+ // JS attempts to move the image CAPTCHA below this part of the form,
+ // so skip one index.
+ $tabIndex++;
+ ?>
+ <div class="mw-submit">
+ <input type='submit' class="mw-ui-button mw-ui-big mw-ui-block mw-ui-primary" name="wpCreateaccount" id="wpCreateaccount"
+ tabindex="<?php echo $tabIndex++; ?>"
+ value="<?php $this->msg( 'createaccount' ); ?>" />
+ </div>
+ <input type="hidden" id="useNew" name="useNew" value="1" />
+<?php if ( $this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
+<?php if ( $this->haveData( 'token' ) ) { ?><input type="hidden" name="wpCreateaccountToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?>
+</form>
+</div>
+<div class="mw-createacct-benefits-container">
+ <h2><?php $this->msg( 'createacct-benefit-heading' ); ?></h2>
+ <div class="mw-createacct-benefits-list">
+ <div>
+ <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon1' ); ?>"></div>
+ <div class="mw-number-text">
+ <h3><?php $this->msg( 'createacct-benefit-head1' ); ?></h3>
+ <p><?php $this->msg( 'createacct-benefit-body1' ); ?></p>
+ </div>
+ </div>
+ <div>
+ <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon2' ); ?>"></div>
+ <div class="mw-number-text">
+ <h3><?php $this->msg( 'createacct-benefit-head2' ); ?></h3>
+ <p><?php $this->msg( 'createacct-benefit-body2' ); ?></p>
+ </div>
+ </div>
+ <div>
+ <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon3' ); ?>"></div>
+ <div class="mw-number-text">
+ <h3><?php $this->msg( 'createacct-benefit-head3' ); ?></h3>
+ <p><?php $this->msg( 'createacct-benefit-body3' ); ?></p>
+ </div>
+ </div>
+ </div>
+</div>
+</div>
+<?php
+
+ }
+}
?>
<div class="mw-ui-container">
<?php
- // Some extensions including CAPTCHAs add content to header on UserLoginForm hook.
- $this->html( 'header' );
if ( $this->haveData( 'languages' ) ) {
?>
<div id="languagelinks">
?>
<div id="userloginForm">
<form name="userlogin" class="mw-ui-vform" method="post" action="<?php $this->text( 'action' ); ?>">
+ <section class="mw-form-header">
+ <?php $this->html( 'header' ); /* extensions such as ConfirmEdit add form HTML here */ ?>
+ </section>
<?php
if ( $this->data['message'] ) {
* @since 1.18
*/
public function formatExpiry( $expiry, $format = true ) {
- static $infinity, $infinityMsg;
+ static $infinity;
if ( $infinity === null ) {
- $infinityMsg = wfMessage( 'infiniteblock' );
$infinity = wfGetDB( DB_SLAVE )->getInfinity();
}
if ( $expiry == '' || $expiry == $infinity ) {
return $format === true
- ? $infinityMsg
+ ? $this->getMessageFromDB( 'infiniteblock' )
: $infinity;
} else {
return $format === true
'nov' => 'নৱেম্বৰ:',
'dec' => 'ডিচেম্বৰ:',
+'monday-at' => 'সোমবাৰে $1ত',
+'tuesday-at' => 'মঙ্গলবাৰে $1’ত',
+'wednesday-at' => 'বুধবাৰে $1’ত',
+'thursday-at' => 'বৃহস্পতিবাৰে $1’ত',
+'friday-at' => 'শুক্ৰবাৰে $1’ত',
+'saturday-at' => 'শনিবাৰে $1’ত',
+'sunday-at' => 'দেওবাৰে $1’ত',
+'today-at' => '$1',
+'yesterday-at' => 'কালি $1’ত',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|শ্ৰেণী|শ্ৰেণীসমূহ}}',
'category_header' => '"$1" শ্ৰেণীৰ পৃষ্ঠাসমূহ',
'duration-centuries' => '$1 {{PLURAL:$1|শতাব্দী|শতাব্দী}}',
'duration-millennia' => '$1 {{PLURAL:$1|সহস্ৰাব্দ|সহস্ৰাব্দ}}',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|ঘন্টা}} আগেয়ে',
+'minutes-ago' => '$1 {{PLURAL:$1|মাহ}} আগেয়ে',
+'seconds-ago' => '$1 {{PLURAL:$1|ছেকেন্ড}} আগতে',
);
'welcomecreation-msg' => 'Иҫәп яҙыуығыҙ яһалды.
Шәхси [[Special:Preferences|{{SITENAME}} көйләүҙәрен]] үҙегеҙгә уңайлы итеп үҙгәртергә онотмағыҙ.',
'yourname' => 'Ҡатнашыусы исеме',
+'userlogin-yourname' => 'Ҡулланыусы исеме',
'yourpassword' => 'Һеҙҙең пароль',
+'userlogin-yourpassword' => 'Пароль',
+'userlogin-yourpassword-ph' => 'Яңы паролде яҙығыҙ',
'yourpasswordagain' => 'Паролде ҡабаттан яҙыу',
'remembermypassword' => 'Был компьютерҙа паролемде иҫләргә ($1 {{PLURAL:$1|көндән|көндән}} күп түгел)',
+'userlogin-remembermypassword' => 'Хәтерҙә ҡалдырырға',
'securelogin-stick-https' => 'Танылғандан һуң HTTPS менән бәйләнеште ҡалдырырға',
'yourdomainname' => 'Һеҙҙең домен',
'password-change-forbidden' => 'Был викила паролегеҙҙе үҙгәртә алмайһығыҙ.',
'nov' => 'ліс',
'dec' => 'сьн',
+'monday-at' => 'Панядзелак, $1',
+'tuesday-at' => 'Аўторак, $1',
+'wednesday-at' => 'Серада, $1',
+'thursday-at' => 'Чацьвер, $1',
+'friday-at' => 'Пятніца, $1',
+'saturday-at' => 'Субота, $1',
+'sunday-at' => 'Нядзеля, $1',
+'today-at' => '$1',
+'yesterday-at' => 'Учора, $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Катэгорыя|Катэгорыі|Катэгорыі}}',
'category_header' => 'Старонкі ў катэгорыі «$1»',
# Image rotation
'rotate-comment' => 'Выява павернутая на $1{{PLURAL:$1|°}} па гадзіньнікавай стрэлцы',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|гадзіну|гадзіны|гадзінаў}} таму',
+'minutes-ago' => '$1 {{PLURAL:$1|хвіліну|хвіліны|хвілінаў}} таму',
+'seconds-ago' => '$1 {{PLURAL:$1|сэкунду|сэкунды|сэкундаў}} таму',
);
'userlogout' => 'প্রস্থান',
'notloggedin' => 'আপনি সংযুক্ত নন',
'userlogin-noaccount' => 'কোনও অ্যাকাউন্ট নেই?',
-'userlogin-joinproject' => '{{SITENAME}}য় অংশগ্রহন করুন',
+'userlogin-joinproject' => '{{SITENAME}}-এ অংশগ্রহন করুন',
'nologin' => "আপনার কি উইকিপিডিয়াতে অ্যাকাউন্ট নেই? তাহলে '''$1'''।",
'nologinlink' => 'অ্যাকাউন্ট তৈরি করুন',
'createaccount' => 'নতুন অ্যাকাউন্ট খুলুন',
'page_last' => 'тlаьххьара',
'histlegend' => "Кхетор: (хlинцлера.) — йолучу башхон къастам; (хьалх.) — хьалхлерачу башхон къастам; '''ж''' — жимо бозалца болу хийцам.",
'history-fieldset-title' => 'Хьажа исцlарерачу',
-'histfirst' => 'къена',
-'histlast' => 'Ñ\85Ñ\8cалÑ\85о',
+'histfirst' => 'ширниш',
+'histlast' => 'Ñ\85Ñ\8cалÑ\85аÑ\80ниÑ\88',
'historyempty' => '(йаьсса)',
# Revision feed
'movethispage' => 'Хlокху агlон цlе хийца',
'unusedimagestext' => 'Дехар до, тидаме эца, кхин йолу дуьнана машан-меттигаш а лелош хила мега нисса йогlу хьажориг (URL) хlокху хlуман, хlокху могlаме йогlуш ялахь яцахь а иза хила мега жигара лелош.',
'pager-newer-n' => '{{PLURAL:$1|алсамо керла|алсамо керланаш|алсамо керлачарех}} $1',
-'pager-older-n' => '{{PLURAL:$1|алсамо къена|алсамо къенанаш|алсамо къеначарех}} $1',
+'pager-older-n' => '{{PLURAL:$1|алсамо шира|алсамо ширниш|алсамо ширачарех}} $1',
# Book sources
'booksources' => 'Жайнан хьосташ',
'hijri-calendar-m3' => 'ڕەبیعەلئەووەڵ',
'hijri-calendar-m4' => 'ڕەبیعەلئاخیر',
'hijri-calendar-m5' => 'جومادەلئوولا',
-'hijri-calendar-m6' => 'جومادەسسانی',
+'hijri-calendar-m6' => 'جومادەلئاخیر',
'hijri-calendar-m7' => 'ڕەجەب',
'hijri-calendar-m8' => 'شەعبان',
'hijri-calendar-m9' => 'ڕەمەزان',
'nov' => '11.',
'dec' => '12.',
+'monday-at' => 'v pondělí v $1',
+'tuesday-at' => 'v úterý v $1',
+'wednesday-at' => 've středu v $1',
+'thursday-at' => 've čtvrtek v $1',
+'friday-at' => 'v pátek v $1',
+'saturday-at' => 'v sobotu v $1',
+'sunday-at' => 'v neděli v $1',
+'today-at' => '$1',
+'yesterday-at' => 'včera v $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategorie|Kategorie|Kategorie}}',
'category_header' => 'Stránky v kategorii „$1“',
# Image rotation
'rotate-comment' => 'Obrázek otočen o $1 {{PLURAL:$1|stupeň|stupně|stupňů}} po směru hodinových ručiček',
+# Unknown messages
+'hours-ago' => 'před $1 {{PLURAL:$1|hodinou|hodinami}}',
+'minutes-ago' => 'před $1 {{PLURAL:$1|minutou|minutami}}',
+'seconds-ago' => 'před $1 {{PLURAL:$1|sekundou|sekundami}}',
);
'watchmethod-list' => 'Tjekker seneste ændringer for sider i din overvågningsliste',
'watchlistcontains' => 'Din overvågningsliste indeholder $1 {{PLURAL:$1|side|sider}}.',
'iteminvalidname' => "Problem med '$1', ugyldigt navn...",
-'wlnote' => "Nedenfor ses {{PLURAL:$1|den seneste ændring|de seneste '''$1''' ændringer}} i {{PLURAL:$2|den sidste time|'''de sidste $2 timer}}''' fra den $3, kl. $4.",
+'wlnote' => "Nedenfor ses {{PLURAL:$1|den seneste ændring|de seneste '''$1''' ændringer}} i {{PLURAL:$2|den sidste time|'''de sidste $2 timer}}''' op til den $3 kl. $4.",
'wlshowlast' => 'Vis de seneste $1 timer $2 dage $3',
'watchlist-options' => 'Indstillinger for overvågningslisten',
'nov' => 'Nov.',
'dec' => 'Dez.',
+'monday-at' => 'Montag um $1',
+'tuesday-at' => 'Dienstag um $1',
+'wednesday-at' => 'Mittwoch um $1',
+'thursday-at' => 'Donnerstag um $1',
+'friday-at' => 'Freitag um $1',
+'saturday-at' => 'Samstag um $1',
+'sunday-at' => 'Sonntag um $1',
+'today-at' => '$1',
+'yesterday-at' => 'Gestern um $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategorie|Kategorien}}',
'category_header' => 'Seiten in der Kategorie „$1“',
'searchprofile-advanced' => 'Erweitert',
'searchprofile-articles-tooltip' => 'Suchen in $1',
'searchprofile-project-tooltip' => 'Suchen in $1',
-'searchprofile-images-tooltip' => 'Nach Bildern suchen',
+'searchprofile-images-tooltip' => 'Nach Dateien suchen',
'searchprofile-everything-tooltip' => 'Gesamten Inhalt durchsuchen (inklusive Diskussionsseiten)',
'searchprofile-advanced-tooltip' => 'Suche in weiteren Namensräumen',
'search-result-size' => '$1 ({{PLURAL:$2|1 Wort|$2 Wörter}})',
'rc-change-size' => '$1 {{PLURAL:$1|Byte|Bytes}}',
'rc-change-size-new' => '$1 {{PLURAL:$1|Byte|Bytes}} nach der Änderung',
'newsectionsummary' => 'Neuer Abschnitt /* $1 */',
-'rc-enhanced-expand' => 'Details anzeigen (benötigt JavaScript)',
-'rc-enhanced-hide' => 'Details verstecken',
+'rc-enhanced-expand' => 'Einzelheiten anzeigen (benötigt JavaScript)',
+'rc-enhanced-hide' => 'Einzelheiten verstecken',
'rc-old-title' => 'ursprünglich erstellt als „$1“',
# Recent changes linked
'minutes' => '{{PLURAL:$1|$1 Minute|$1 Minuten}}',
'hours' => '{{PLURAL:$1|1 Stunde|$1 Stunden}}',
'days' => '{{PLURAL:$1|$1 Tag|$1 Tage}}',
+'weeks' => '{{PLURAL:$1|$1 Woche|$1 Wochen}}',
'months' => '{{PLURAL:$1|1 Monat|$1 Monate}}',
'years' => '{{PLURAL:$1|1 Jahr|$1 Jahre}}',
'ago' => 'vor $1',
# Image rotation
'rotate-comment' => 'Bild um $1 {{PLURAL:$1|Grad}} im Uhrzeigersinn gedreht',
+# Unknown messages
+'hours-ago' => 'vor {{PLURAL:$1|einer Stunde|$1 Stunden}}',
+'minutes-ago' => 'vor {{PLURAL:$1|einer Minute|$1 Minuten}}',
+'seconds-ago' => 'vor {{PLURAL:$1|einer Sekunde|$1 Sekunden}}',
);
'brokenredirects-edit' => 'bıvurne',
'brokenredirects-delete' => 'bestere',
-'withoutinterwiki' => 'Peleyê ke zıwanan de bina re gırey cı çınyo',
+'withoutinterwiki' => 'Pelê ke zıwananê binan rê gıreyê cı çıniyo',
'withoutinterwiki-summary' => 'Enê pelî ke versiyonê ziwanî binî ra link nidano.',
'withoutinterwiki-legend' => 'Verole',
'withoutinterwiki-submit' => 'Bımocne',
-'fewestrevisions' => 'Peleyê ke cı sero tewr tayn timaryayış vıraziyayo',
+'fewestrevisions' => 'Pelê be senık çımraviyarnayışi',
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|bayt|bayti}}',
'uncategorizedpages' => 'Pelayanê ke kategorî nibiye',
'uncategorizedcategories' => 'Kategoriyê ke bê kategorîyê',
'uncategorizedimages' => 'Dosyayê ke bê kategoriyê',
-'uncategorizedtemplates' => 'Şablonê ke bê kategoriyê',
+'uncategorizedtemplates' => 'Şablonê ke bêkategoriyê',
'unusedcategories' => 'Kategoriyê ke nê xebtênê',
'unusedimages' => 'Dosyeyê ke nê xebtênê',
'popularpages' => 'Pelî ke populer o.',
'wantedcategories' => 'Kategoriye ke waştênê',
'wantedpages' => 'Peleye ke waştênê',
'wantedpages-badtitle' => 'sernuşte meqbul niyo: $1',
-'wantedfiles' => 'Dosyeye ke waştênê',
+'wantedfiles' => 'Dosyeyê cıgeyriyayey',
'wantedfiletext-cat' => 'Dosyaya cêrên karvıstedeya lakin çınya. Mewcud dosyayan de xeriba miyan de liste bena. Xırabiya wınisin dana <del>ateber</del>. Zewbi zi, şırê pela da dosyeyê ke çınyaya [[:$1]].',
'wantedfiletext-nocat' => 'Dosyeyê cêrêni estê lekin karnêvıstê. Dosyeyê xeribi liste benê. bo babeta dano <del>ateber</del>',
-'wantedtemplates' => 'Şablonê ke waştênê',
+'wantedtemplates' => 'Şablonê ke waziyenê',
'mostlinked' => 'Pelî ke tewr zafî lînk bîy.',
'mostlinkedcategories' => 'Kategorî ke tewr zafî lînk bîy.',
'mostlinkedtemplates' => 'Şablonê ke tewr zafî pela re gıre bîye.',
'prefixindex-namespace' => 'Peleyê Veroleyıni ($1 cay nami)',
'shortpages' => 'Pelê kılmeki',
'longpages' => 'Peleyê dergeki',
-'deadendpages' => 'pelê ke pelê binan re gırey nêeşto',
+'deadendpages' => 'Pelê nêgıredayey',
'deadendpagestext' => 'Ena pelan ke {{SITENAME}} de zerrî ey de link çini yo.',
-'protectedpages' => 'Pelayê ke biyê star',
+'protectedpages' => 'Pelê pawıtiyey',
'protectedpages-indef' => 'têna pawıteyê bêmuddeti',
'protectedpages-cascade' => 'Kilit biyaye ke teyna cascadiye',
'protectedpagestext' => 'pelê cêrınî pawiyenê',
'protectedpagesempty' => 'pê ney parametreyan pelê pawiteyi çinî',
-'protectedtitles' => 'Sernameyê ke starênê',
+'protectedtitles' => 'Sernameyê pawıtiyey',
'protectedtitlestext' => 'sernameyê cêrıni pawıte yî',
'protectedtitlesempty' => 'pê ney parametreyan sernuşteyê pawite çinê',
'listusers' => 'Listeyê Karberan',
'restriction-upload' => 'Bar ke',
# Restriction levels
-'restriction-level-sysop' => 'pawıtışê tamamîye',
-'restriction-level-autoconfirmed' => 'nêm-pawıtış',
-'restriction-level-all' => 'seviye ya ke raşt ame',
+'restriction-level-sysop' => 'tam pawiyayo',
+'restriction-level-autoconfirmed' => 'nêm pawiyayo',
+'restriction-level-all' => 'heme yew sewiya',
# Undelete
'undelete' => 'Peleyê ke besterneyayê enê bımocnê',
* Xısusi pelaya normal
* <span class="mw-specialpagerestricted">Xısusi peleyê keı rê ray nê deyaya.</span>
* <strong class="mw-specialpagerestricted">Peleya xısusiya ke grota verhefıza.</strong>',
-'specialpages-group-maintenance' => 'Raporê pak tepiştîşî',
+'specialpages-group-maintenance' => 'Raporê tepıştışi',
'specialpages-group-other' => 'Pelê xasiyê bini',
'specialpages-group-login' => 'Cı kewe / hesab vıraze',
'specialpages-group-changes' => 'Vurnayişê peni u logan',
'specialpages-group-media' => 'Raporê medya u bar kerdîşî',
'specialpages-group-users' => 'Karber u heqqî',
'specialpages-group-highuse' => 'Peleyê ke vêşi karênê',
-'specialpages-group-pages' => 'listeyanê pelan',
+'specialpages-group-pages' => 'Listeyê pelan',
'specialpages-group-pagetools' => 'Haletê pelan',
'specialpages-group-wiki' => 'Melumat u haceti',
'specialpages-group-redirects' => 'Pela xasîyê ke heteneyayê',
'fullpagenamee' => array( 1, 'FULLPAGENAMEE' ),
'subpagename' => array( 1, 'SUBPAGENAME' ),
'subpagenamee' => array( 1, 'SUBPAGENAMEE' ),
+ 'rootpagename' => array( 1, 'ROOTPAGENAME' ),
+ 'rootpagenamee' => array( 1, 'ROOTPAGENAMEE' ),
'basepagename' => array( 1, 'BASEPAGENAME' ),
'basepagenamee' => array( 1, 'BASEPAGENAMEE' ),
'talkpagename' => array( 1, 'TALKPAGENAME' ),
'yourname' => 'Username:',
'userlogin-yourname' => 'Username',
'userlogin-yourname-ph' => 'Enter your username',
+'createacct-helpusername-url' => '{{ns:Project}}:Username_policy',
+'createacct-helpusername-link' => '[[{{MediaWiki:createacct-helpusername-url}}|(help me choose)]]',
'yourpassword' => 'Password:',
'userlogin-yourpassword' => 'Password',
'userlogin-yourpassword-ph' => 'Enter your password',
+'createacct-yourpassword-ph' => 'Enter a password',
'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' => 'Remember me',
'userlogin-signwithsecure' => 'Sign in with secure server',
'userlogin-resetlink' => 'Forgotten your login details?',
'helplogin-url' => 'Help:Logging in',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Help with logging in]]',
+'createacct-join' => 'Enter your information below.',
+'createacct-emailrequired' => 'Email address',
+'createacct-emailoptional' => 'Email address (optional)',
+'createacct-email-ph' => 'Enter your email address',
'createaccountmail' => 'Use a temporary random password and send it to the email address specified below',
+'createacct-realname' => 'Real name (optional)',
'createaccountreason' => 'Reason:',
+'createacct-reason' => 'Reason',
+'createacct-captcha' => 'Security check',
+'createacct-captcha-help-url' => '{{ns:Project}}:Request an account',
+'createacct-imgcaptcha-help' => 'Can\'t see the image? [[{{MediaWiki:createacct-captcha-help-url}}|Request an account]]',
+'createacct-imgcaptcha-ph' => 'Enter the text you see above',
+'createacct-benefit-heading' => '{{SITENAME}} is made by people like you.',
+'createacct-benefit-icon1' => 'icon-edits',
+'createacct-benefit-head1' => '{{NUMBEROFEDITS}}',
+'createacct-benefit-body1' => 'edits',
+'createacct-benefit-icon2' => 'icon-pages',
+'createacct-benefit-head2' => '{{NUMBEROFARTICLES}}',
+'createacct-benefit-body2' => 'pages',
+'createacct-benefit-icon3' => 'icon-contributors',
+'createacct-benefit-head3' => '{{NUMBEROFUSERS}}',
+'createacct-benefit-body3' => 'contributors this month',
'badretype' => 'The passwords you entered do not match.',
'userexists' => 'Username entered already in use.
Please choose a different name.',
'nov' => 'Nov',
'dec' => 'Dec',
+'today-at' => '$1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategorio|Kategorioj}}',
'category_header' => 'Artikoloj en kategorio "$1"',
'welcomecreation-msg' => 'Via konto estas kreita.
Ne forgesu ŝanĝi viajn [[Special:Preferences|{{SITENAME}}-preferojn]]',
'yourname' => 'Salutnomo:',
+'userlogin-yourname' => 'Uzantonomo',
+'userlogin-yourname-ph' => 'Enigu vian uzantonomon',
'yourpassword' => 'Pasvorto:',
+'userlogin-yourpassword' => 'Pasvorto',
+'userlogin-yourpassword-ph' => 'Enigu vian pasvorton',
'yourpasswordagain' => 'Retajpu pasvorton',
'remembermypassword' => 'Memori mian ensalutadon ĉe ĉi tiu komputilo (daŭrante maksimume $1 {{PLURAL:$1|tagon|tagojn}})',
+'userlogin-remembermypassword' => 'Memoru min',
'securelogin-stick-https' => 'Resti konektita al HTTPS post ensalutado',
'yourdomainname' => 'Via domajno',
'password-change-forbidden' => 'Ve ne povas ŝanĝi pasvortojn en ĉi tiu vikio.',
'logout' => 'Elsaluti',
'userlogout' => 'Elsaluti',
'notloggedin' => 'Ne ensalutinta',
+'userlogin-noaccount' => 'Ĉu vi ne havas konton?',
'nologin' => "Ĉu vi ne havas konton? '''$1'''.",
'nologinlink' => 'Krei konton',
'createaccount' => 'Krei novan konton',
'gotaccount' => "Ĉu vi jam havas konton? '''$1'''.",
'gotaccountlink' => 'Ensaluti',
'userlogin-resetlink' => 'Ĉu vi forgesis ensalutajn detalojn?',
+'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Helpo pri ensalutado]]',
'createaccountmail' => 'Uzi provizoran hazardsignan pasvorton kaj sendi ĝin al la retpoŝto suben',
'createaccountreason' => 'Kialo:',
'badretype' => 'La pasvortojn kiujn vi tajpis ne egalas.',
# Email sending
'php-mail-error-unknown' => 'Nekonata eraro en la funkcio mail() de PHP',
'user-mail-no-addy' => 'Provis sendi retpoŝton sen retpoŝtadreso.',
+'user-mail-no-body' => 'Provo sendi malplenan aŭ sensence mallongan retpošton.',
# Change password dialog
'resetpass' => 'Ŝanĝi pasvorton',
# Special:PasswordReset
'passwordreset' => 'Restarigo de pasvorto',
-'passwordreset-text' => 'Plenumigu ĉi tiun formularon por ricevi retpoŝtan memoraĵon de viaj kontaj detaloj.',
+'passwordreset-text' => 'Plenigu ĉi tiun formularon por renovigi vian pasvorton.',
'passwordreset-legend' => 'Refari pasvorton',
'passwordreset-disabled' => 'Pasvortaj restarigoj estis malŝaltitaj en ĉi tiu vikio.',
+'passwordreset-emaildisabled' => 'Retpoŝtaj funkcioj estas malfunkciigitaj en tiu ĉi vikio.',
'passwordreset-pretext' => '{{PLURAL:$1||Enigi unu el la jenaj datenoj}}',
'passwordreset-username' => 'Salutnomo:',
'passwordreset-domain' => 'Domajno:',
ĝin, vi povas ignori ĉi tiun mesaĝon kaj uzi vian malnovan pasvorton.',
'passwordreset-emailelement' => 'Salutnomo: $1
Provizora pasvorto: $2',
-'passwordreset-emailsent' => 'Rememoriga retpoŝto estis sendita.',
-'passwordreset-emailsent-capture' => 'Memoriga retpoŝto estis sendita, kiu estas montrata sube.',
-'passwordreset-emailerror-capture' => 'Memoriga retpoŝto estis generita, montrata sube, sed sendado al uzanto malsukcesis: $1',
+'passwordreset-emailsent' => 'Renovigita pasvorto estis retpoŝte sendita.',
+'passwordreset-emailsent-capture' => 'Retpoŝto kun renovigita pasvorto estis sendita, kiu estas montrata sube.',
+'passwordreset-emailerror-capture' => 'Retpoŝto kun renovigita pasvorto estis generita, montrata sube, sed sendado al uzanto malsukcesis: $1',
# Special:ChangeEmail
'changeemail' => 'Ŝanĝi retpoŝtadreson',
'search-interwiki-default' => '$1 rezultoj:',
'search-interwiki-more' => '(plu)',
'search-relatedarticle' => 'Relataj',
-'mwsuggest-disable' => 'Malŝalti AJAX-sugestojn',
+'mwsuggest-disable' => 'Malŝalti serĉajn sugestojn',
'searcheverything-enable' => 'Traserĉi ĉiujn nomspacojn',
'searchrelated' => 'rilataj',
'searchall' => 'ĉiuj',
'search-external' => 'Ekstera serĉo',
'searchdisabled' => '<p>Oni provizore malŝaltis serĉadon per la plenteksta
indekso pro troŝarĝita servilo. Intertempe, vi povas serĉi per <i>guglo</i> aŭ per <i>jahu!</i>:</p>',
+'search-error' => 'Okazis eraro dum serĉado: $1',
# Preferences page
'preferences' => 'Preferoj',
'prot_1movedto2' => '[[$1]] movita al [[$2]]',
'protect-badnamespace-title' => 'Ne-protektebla nomspaco',
'protect-badnamespace-text' => 'Paĝoj en ĉi tiu datumbazo ne povas esti protektita.',
+'protect-norestrictiontypes-title' => 'Neprotektebla paĝo',
'protect-legend' => 'Konfirmi protektadon',
'protectcomment' => 'Kialo:',
'protectexpiry' => 'Eksvalidiĝas:',
'protect-cascadeon' => 'Ĉi paĝo estas nun protektita kontraŭ redaktado ĉar ĝi estas inkluzivita en {{PLURAL:$1|jena paĝo, kiu mem estas protektita|jenaj paĝoj, kiuj mem estas protektitaj}} per kaskada protekto.
Vi povas ŝanĝi ties protektnivelon, sed tio ne ŝanĝos la kaskadan protekton.',
'protect-default' => 'Permesigi ĉiujn uzantojn',
-'protect-fallback' => 'Rajto "$1" nepras.',
+'protect-fallback' => 'Permesi nur uzantojn kun la rajto "$1"',
'protect-level-autoconfirmed' => 'Bloki novajn kaj neregistritajn uzantojn',
-'protect-level-sysop' => 'Nur administrantoj',
+'protect-level-sysop' => 'Permesi nur administrantojn',
'protect-summary-cascade' => 'kaskada',
'protect-expiring' => 'finiĝas je $1 (UTC)',
'protect-expiring-local' => 'eksdatiĝas $1',
'pageinfo-robot-noindex' => 'Ne indeksebla',
'pageinfo-views' => 'Nombro de rigardoj',
'pageinfo-watchers' => 'Nombro de paĝatentantoj',
+'pageinfo-few-watchers' => 'Malpli ol $1 {{PLURAL:$1|atentanto|atentantoj}}',
'pageinfo-redirects-name' => 'Alidirektoj al ĉi tiu paĝo',
'pageinfo-subpages-name' => 'Subpaĝoj de ĉi tiu paĝo',
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|alidirektilo|alidirektiloj}}; $3 {{PLURAL:$3|ne-alidirektilo|ne-alidirektiloj}})',
'minutes' => '{{PLURAL:$1|$1 minuto|$1 minutoj}}',
'hours' => '{{PLURAL:$1|$1 horo|$1 horoj}}',
'days' => '{{PLURAL:$1|$1 tago|$1 tagoj}}',
+'weeks' => '{{PLURAL:$1|$1 semajno|$1 semajnoj}}',
'months' => '{{PLURAL:$1|$1 monato|$1 monatoj}}',
'years' => '{{PLURAL:$1|$1 jaro|$1 jaroj}}',
'ago' => 'antaŭ $1',
'htmlform-submit' => 'Ek!',
'htmlform-reset' => 'Malfari ŝanĝojn',
'htmlform-selectorother-other' => 'Alia',
+'htmlform-no' => 'Ne',
+'htmlform-yes' => 'Jes',
# SQLite database support
'sqlite-has-fts' => '$1 kun tut-teksta subteno',
'logentry-delete-restore' => '$1 restarigis paĝon $3',
'logentry-delete-event' => '$1 ŝanĝis videblecon de {{PLURAL:$5|protokola evento|$5 protokolaj eventoj}} je $3: $4',
'logentry-delete-revision' => '$1 ŝanĝis videblecon de {{PLURAL:$5|revizio|$5 reviziojn}} je paĝo $3: $4',
-'logentry-delete-event-legacy' => '$1 ŝanĝis vidiblecon de protokolaj eventoj en $3',
-'logentry-delete-revision-legacy' => '$1 ŝanĝis vidiblecon de revizioj en $3',
+'logentry-delete-event-legacy' => '$1 ŝanĝis videblecon de protokolaj eventoj en $3',
+'logentry-delete-revision-legacy' => '$1 ŝanĝis videblecon de revizioj en $3',
'logentry-suppress-delete' => '$1 kaŝis paĝon $3',
'logentry-suppress-event' => '$1 kaŝite ŝanĝis videblecon de {{PLURAL:$5|protokola evento|$5 protokolaj eventoj}} je $3: $4',
'logentry-suppress-revision' => '$1 kaŝite ŝanĝis videblecon de {{PLURAL:$5|revizio|$5 reviziojn}} je paĝo $3: $4',
-'logentry-suppress-event-legacy' => '$1 kaŝite ŝanĝis vidiblecon de protokolaj eventoj en $3',
-'logentry-suppress-revision-legacy' => '$1 kaŝite ŝanĝis vidiblecon de revizioj en paĝo $3',
+'logentry-suppress-event-legacy' => '$1 kaŝite ŝanĝis videblecon de protokolaj eventoj en $3',
+'logentry-suppress-revision-legacy' => '$1 kaŝite ŝanĝis videblecon de revizioj en paĝo $3',
'revdelete-content-hid' => 'enhavo kaŝita',
'revdelete-summary-hid' => 'resumo de redakto kaŝita',
'revdelete-uname-hid' => 'salutnomo kaŝita',
'revdelete-restricted' => 'aplikis limojn al administrantoj',
'revdelete-unrestricted' => 'forigis limojn por administrantoj',
'logentry-move-move' => '$1 movis paĝon $3 al $4',
-'logentry-move-move-noredirect' => '$1 movis paĝon $3 al $4 sen lasante alidirektilon',
+'logentry-move-move-noredirect' => '$1 movis paĝon $3 al $4 ne lasante alidirektilon',
'logentry-move-move_redir' => '$1 movis paĝon $3 al $4 anstataŭigante alidirektilon',
-'logentry-move-move_redir-noredirect' => '$1 movis paĝon $3 al $4 anstataŭigante alidirektilon sen lasante alidirektilon',
-'logentry-patrol-patrol' => '$1 markis revizion $4 de paĝo $3 kiel patrolita',
-'logentry-patrol-patrol-auto' => '$1 aŭtomate markis revizion $4 de paĝo $3 kiel patrolita',
-'logentry-newusers-newusers' => '$1 kreis konton',
-'logentry-newusers-create' => '$1 kreis konton',
-'logentry-newusers-create2' => '$1 kreis uzanton $3',
-'logentry-newusers-autocreate' => 'Konto $1 estis kreita aŭtomate',
+'logentry-move-move_redir-noredirect' => '$1 movis paĝon $3 al $4 anstataŭigante alidirektilon ne lasante alidirektilon',
+'logentry-patrol-patrol' => '$1 markis revizion $4 de paĝo $3 patrolita',
+'logentry-patrol-patrol-auto' => '$1 aŭtomate markis revizion $4 de paĝo $3 patrolita',
+'logentry-newusers-newusers' => 'Konto de uzanto $1 estis kreita',
+'logentry-newusers-create' => 'Konto de uzanto $1 estis kreita',
+'logentry-newusers-create2' => 'Konto de uzanto $3 estis kreita de $1',
+'logentry-newusers-byemail' => 'Konto de uzanto $3 estis kreita de $1 kaj pasvorto estis sendita per retpoŝto',
+'logentry-newusers-autocreate' => 'Uzantokonto $1 estis kreita aŭtomate',
'logentry-rights-rights' => '$1 ŝanĝis grupan membrecon por $3 de $4 al $5',
'logentry-rights-rights-legacy' => '$1 ŝanĝis grupan membrecon por $3',
'logentry-rights-autopromote' => '$1 estis aŭtomate {{GENDER:$2|altrangigita}} de $4 al $5',
'duration-centuries' => '$1 {{PLURAL:$1|jarcento|jarcentoj}}',
'duration-millennia' => '$1 {{PLURAL:$1|jarmilo|jarmiloj}}',
+# Unknown messages
+'hours-ago' => 'antaŭ $1 {{PLURAL:$1|horo|horoj}}',
+'minutes-ago' => 'antaŭ $1 {{PLURAL:$1|minuto|minutoj}}',
+'seconds-ago' => 'antaŭ $1 {{PLURAL:$1|sekundo|sekundoj}}',
);
'nov' => 'nov',
'dec' => 'dic',
+'monday-at' => 'El lunes a las $1',
+'tuesday-at' => 'El martes a las $1',
+'wednesday-at' => 'El miércoles a las $1',
+'thursday-at' => 'El jueves a las $1',
+'friday-at' => 'El viernes a las $1',
+'saturday-at' => 'El sábado a las $1',
+'sunday-at' => 'El domingo a las $1',
+'today-at' => '$1',
+'yesterday-at' => 'Ayer a las $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categoría|Categorías}}',
'category_header' => 'Artículos en la categoría «$1»',
# Image rotation
'rotate-comment' => 'Imagen girada por $1 {{PLURAL:$1|grado|grados}} en el sentido de las agujas del reloj',
+# Unknown messages
+'hours-ago' => 'hace $1 {{PLURAL:$1|hora|horas}}',
+'minutes-ago' => 'hace {{PLURAL:$1|un minuto|$1 minutos}}',
+'seconds-ago' => 'hace $1 {{PLURAL:$1|segundo|segundos}}',
);
'nov' => 'نوامبر',
'dec' => 'دسامبر',
+'monday-at' => 'دوشنبهٔ $1',
+'tuesday-at' => 'سهشنبهٔ $1',
+'wednesday-at' => 'چهارشنبهٔ $1',
+'thursday-at' => 'پنجشنبهٔ $1',
+'friday-at' => 'جمعهٔ $1',
+'saturday-at' => 'شنبهٔ $1',
+'sunday-at' => 'یکشنبهٔ $1',
+'today-at' => '$1',
+'yesterday-at' => 'دیروز $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|رده|ردهها}}',
'category_header' => 'صفحههای ردهٔ «$1»',
# Image rotation
'rotate-comment' => 'تصویر به دست $1 {{PLURAL:$1|درجهٔ|درجهٔ}} ساعتگرد چرخانده شد',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|ساعت|ساعت}} قبل',
+'minutes-ago' => '$1 {{PLURAL:$1|دقیقه|دقیقه}} قبل',
+'seconds-ago' => '$1 {{PLURAL:$1|ثانیه|ثانیه}} قبل',
);
'nov' => 'nov',
'dec' => 'déc',
+'monday-at' => 'Lundi à $1',
+'tuesday-at' => 'Mardi à $1',
+'wednesday-at' => 'Mercredi à $1',
+'thursday-at' => 'Jeudi à $1',
+'friday-at' => 'Vendredi à $1',
+'saturday-at' => 'Samedi à $1',
+'sunday-at' => 'Dimanche à $1',
+'today-at' => '$1',
+'yesterday-at' => 'Hier à $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Catégorie|Catégories}}',
'category_header' => 'Pages dans la catégorie « $1 »',
'vector-simplesearch-preference' => "Activer la barre de recherche simplifiée (seulement pour l'habillage Vector)",
'vector-view-create' => 'Créer',
'vector-view-edit' => 'Modifier',
-'vector-view-history' => "Afficher l'historique",
+'vector-view-history' => 'Afficher l’historique',
'vector-view-view' => 'Lire',
'vector-view-viewsource' => 'Voir la source',
'actions' => 'Actions',
'minutes' => '{{PLURAL:$1|$1 minute|$1 minutes}}',
'hours' => '{{PLURAL:$1|$1 heure|$1 heures}}',
'days' => '{{PLURAL:$1|$1 jour|$1 jours}}',
+'weeks' => '{{PLURAL:$1|$1 semaine|$1 semaines}}',
'months' => '{{PLURAL:$1|$1 mois}}',
'years' => '{{PLURAL:$1|$1 an|$1 ans}}',
'ago' => 'Il y a $1',
# Image rotation
'rotate-comment' => 'Image pivotée de $1 {{PLURAL:$1|degré|degrés}} dans le sens des aiguilles d’une montre',
+# Unknown messages
+'hours-ago' => 'il y a $1 {{PLURAL:$1|heure|heures}}',
+'minutes-ago' => 'il y a $1 {{PLURAL:$1|minute|minutes}}',
+'seconds-ago' => 'il y a $1 {{PLURAL:$1|seconde|secondes}}',
);
'nov' => "נוב'",
'dec' => "דצמ'",
+'monday-at' => 'ביום שני בשעה $1',
+'tuesday-at' => 'ביום שלישי בשעה $1',
+'wednesday-at' => 'ביום רביעי בשעה $1',
+'thursday-at' => 'ביום חמישי בשעה $1',
+'friday-at' => 'ביום שישי בשעה $1',
+'saturday-at' => 'בשבת בשעה $1',
+'sunday-at' => 'ביום ראשון בשעה $1',
+'today-at' => '$1',
+'yesterday-at' => 'אתמול בשעה $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|קטגוריה|קטגוריות}}',
'category_header' => 'דפים בקטגוריה "$1"',
'minutes' => '{{PLURAL:$1|דקה|$1 דקות}}',
'hours' => '{{PLURAL:$1|שעה|שעתיים|$1 שעות}}',
'days' => '{{PLURAL:$1|יום|יומיים|$1 ימים}}',
+'weeks' => '{{PLURAL:$1|שבוע|שבועיים|$1 שבועות}}',
'months' => '{{PLURAL:$1|חודש|חודשיים|$1 חודשים}}',
'years' => '{{PLURAL:$1|שנה|שנתיים|$1 שנים}}',
'ago' => 'לפני $1',
# Image rotation
'rotate-comment' => 'התמונה סובבה {{PLURAL:$1|במעלה אחת|ב֫־$1 מעלות}} בכיוון השעון',
+# Unknown messages
+'hours-ago' => 'לפני {{PLURAL:$1|שעה|שעתיים|$1 שעות}}',
+'minutes-ago' => 'לפני {{PLURAL:$1|דקה|$1 דקות}}',
+'seconds-ago' => 'לפני {{PLURAL:$1|שנייה|$1 שניות}}',
);
'rc-old-title' => 'prěnjotnje wutworjeny jako "$1"',
# Recent changes linked
-'recentchangeslinked' => 'Změny w zwjazanych stronach',
+'recentchangeslinked' => 'Změny na zwjazanych stronach',
'recentchangeslinked-feed' => 'Změny zwjazanych stron',
-'recentchangeslinked-toolbox' => 'Změny w zwjazanych stronach',
+'recentchangeslinked-toolbox' => 'Změny na zwjazanych stronach',
'recentchangeslinked-title' => 'Změny na stronach, kotrež su z „$1“ wotkazane',
'recentchangeslinked-noresult' => 'Njejsu změny zwajzanych stron we wubranej dobje.',
'recentchangeslinked-summary' => "Tuta strona nalistuje poslednje změny na wotkazanych stronach (resp. pola kategorijow na čłonach kategorije).
'nov' => 'nov',
'dec' => 'dec',
+'monday-at' => 'Lunedi a $1',
+'tuesday-at' => 'Martedi a $1',
+'wednesday-at' => 'Mercuridi a $1',
+'thursday-at' => 'Jovedi a $1',
+'friday-at' => 'Venerdi a $1',
+'saturday-at' => 'Sabbato a $1',
+'sunday-at' => 'Dominica a $1',
+'today-at' => '$1',
+'yesterday-at' => 'Heri a $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categoria|Categorias}}',
'category_header' => 'Articulos in le categoria "$1"',
# Image rotation
'rotate-comment' => 'Imagine rotate de $1 {{PLURAL:$1|grado|grados}} in senso horologic',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|hora|horas}} retro',
+'minutes-ago' => '$1 {{PLURAL:$1|minuta|minutas}} retro',
+'seconds-ago' => '$1 {{PLURAL:$1|secunda|secundas}} retro',
);
'nov' => 'nov',
'dec' => 'dic',
+'monday-at' => 'Lunedì alle $1',
+'tuesday-at' => 'Martedì alle $1',
+'wednesday-at' => 'Mercoledì alle $1',
+'thursday-at' => 'Giovedì alle $1',
+'friday-at' => 'Venerdì alle $1',
+'saturday-at' => 'Sabato alle $1',
+'sunday-at' => 'Domenica alle $1',
+'yesterday-at' => 'Ieri alle $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categoria|Categorie}}',
'category_header' => 'Pagine nella categoria "$1"',
'minutes' => '{{PLURAL:$1|un minuto|$1 minuti}}',
'hours' => "{{PLURAL:$1|un'ora|$1 ore}}",
'days' => '{{PLURAL:$1|$1 giorno|$1 giorni}}',
+'weeks' => '{{PLURAL:$1|$1 settimana|$1 settimane}}',
'months' => '{{PLURAL:$1|$1 mese|$1 mesi}}',
'years' => '{{PLURAL:$1|$1 anno|$1 anni}}',
'ago' => '$1 fa',
# Image rotation
'rotate-comment' => 'Immagine ruotata di $1 {{PLURAL:$1|grado|gradi}} in senso orario',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|ora|ore}} fa',
+'minutes-ago' => '$1 {{PLURAL:$1|minuto|minuti}} fa',
+'seconds-ago' => '$1 {{PLURAL:$1|secondo|secondi}} fa',
);
'nov' => '11月',
'dec' => '12月',
+'monday-at' => '月曜日 $1',
+'tuesday-at' => '火曜日 $1',
+'wednesday-at' => '水曜日 $1',
+'thursday-at' => '木曜日 $1',
+'friday-at' => '金曜日 $1',
+'saturday-at' => '土曜日 $1',
+'sunday-at' => '日曜日 $1',
+'today-at' => '$1',
+'yesterday-at' => '昨日 $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|カテゴリ}}',
'category_header' => 'カテゴリ「$1」にあるページ',
# Image rotation
'rotate-comment' => '画像を時計回りに $1 {{PLURAL:$1|度}}回転',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|時間}}前',
+'minutes-ago' => '$1 {{PLURAL:$1|分}}前',
+'seconds-ago' => '$1 {{PLURAL:$1|秒}}前',
);
'nov' => 'Wam',
'dec' => 'Duj',
+'monday-at' => 'Arim af $1',
+'tuesday-at' => 'Aram af $1',
+'wednesday-at' => 'Ahad af $1',
+'thursday-at' => 'Amhad af $1',
+'friday-at' => 'Sem af $1',
+'saturday-at' => 'Sed af $1',
+'sunday-at' => 'Acer af $1',
+'today-at' => '$1',
+'yesterday-at' => 'Iḍelli af $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Taggayt|Taggayin}}',
'category_header' => 'Imagraden deg taggayt "$1"',
'duration-centuries' => '$1 {{PLURAL:$1|timiḍi|timiḍa}}',
'duration-millennia' => '$1 {{PLURAL:$1|agimseggwas|agimseggwasen}}',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|asrag|isragen}} aya',
+'minutes-ago' => '$1 {{PLURAL:$1|tamrect|timercin}} aya',
+'seconds-ago' => '$1 {{PLURAL:$1|tasint|tisinin}} aya',
);
'specialpages-group-media' => 'Raporê medya u bar-kerdey',
'specialpages-group-users' => 'Karber u heqi',
'specialpages-group-highuse' => 'Pelê jêdêr gurenaey',
-'specialpages-group-pages' => 'Lista pelun',
+'specialpages-group-pages' => 'Listê pelun',
'specialpages-group-pagetools' => 'Hacetê pele',
'specialpages-group-wiki' => "Daê ''Wiki''y u haceti",
'specialpages-group-redirects' => 'Newe-vırastena pelunê xususiyun',
'nov' => '11',
'dec' => '12',
+'monday-at' => '월요일 $1',
+'tuesday-at' => '화요일 $1',
+'wednesday-at' => '수요일 $1',
+'thursday-at' => '목요일 $1',
+'friday-at' => '금요일 $1',
+'saturday-at' => '토요일 $1',
+'sunday-at' => '일요일 $1',
+'today-at' => '$1',
+'yesterday-at' => '어제 $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|분류}}',
'category_header' => '"$1" 분류에 속하는 문서',
# Image rotation
'rotate-comment' => '그림을 시계 방향으로 $1{{PLURAL:$1|도}}로 회전함',
+# Unknown messages
+'hours-ago' => '$1{{PLURAL:$1|시간}} 전',
+'minutes-ago' => '$1{{PLURAL:$1|분}} 전',
+'seconds-ago' => '$1{{PLURAL:$1|초}} 전',
);
'version-parser-function-hooks' => 'Parserfunktione',
'version-hook-name' => 'De Schnettstelle ier Name',
'version-hook-subscribedby' => 'Opjeroofe vun',
-'version-version' => '(Version $1)',
+'version-version' => '(Väsjohn $1)',
'version-license' => 'Lėzänz',
'version-poweredby-credits' => "Dat Wiki heh löp met '''[//www.mediawiki.org/ MediaWiki]''', copyright © 2001–$1 $2.",
'version-poweredby-others' => 'sönß wää',
'userrights-groupsmember' => 'Anggota dari:',
'userrights-groupsmember-auto' => 'Anggota implisit dari:',
'userrights-groups-help' => 'Sanak dapek mangubah kalompok pangguno ko:
-* Kotak jo tando cek marupoan kalompok pangguno tasabuik
-* Kotak tanpa tando cek bararti pangguno ko bukan anggota kalompok tasabuik
-* Tando * manandoi Sanak indak dapek mambatalan kalompok tasabuik bilo Sanak alah manambahannyo, atau sabaliaknyo.',
+* Kotak jo tando centang marupoan kalompok pangguno tasabuik
+* Kotak indak ado tando centang bararti pangguno ko bukan anggota kalompok tasabuik
+* Tando * manandoan Sanak indak dapek mambatalan kalompok tasabuik bilo Sanak alah manambahannyo, ataupun sabaliaknyo.',
'userrights-reason' => 'Alasan:',
'userrights-no-interwiki' => 'Sanak indak bahak untuak mangubah hak pangguno di wiki lain.',
'userrights-nodatabase' => 'Basis data $1 indak ado atau bukan disiko.',
'nov' => 'ное',
'dec' => 'дек',
+'monday-at' => 'понеделникот во $1',
+'tuesday-at' => 'вторникот во $1',
+'wednesday-at' => 'средата во $1',
+'thursday-at' => 'четвртокот во $1',
+'friday-at' => 'петокот во $1',
+'saturday-at' => 'саботата во $1',
+'sunday-at' => 'неделата во $1',
+'today-at' => '$1',
+'yesterday-at' => 'вчера во $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Категорија|Категории}}',
'category_header' => 'Статии во категоријата „$1“',
'hidden-category-category' => 'Скриени категории',
'category-subcat-count' => '{{PLURAL:$2|Оваа категорија ја содржи само следнава поткатегорија.|Оваа категорија {{PLURAL:$1|ја содржи следнава поткатегорија|ги содржи следниве $1 поткатегории}} од вкупно $2.}}',
'category-subcat-count-limited' => 'Оваа категорија {{PLURAL:$1|ја содржи следнава поткатегорија|ги содржи следниве $1 поткатегории}}.',
-'category-article-count' => '{{PLURAL:$2|Ð\9aаÑ\82егоÑ\80иÑ\98аÑ\82а Ñ\98а Ñ\81одÑ\80жи Ñ\81амо Ñ\81леднава Ñ\81Ñ\82Ñ\80аниÑ\86а.|Ð\9aаÑ\82егоÑ\80иÑ\98аÑ\82а {{PLURAL:$1|Ñ\98а Ñ\81одÑ\80жи Ñ\81леднава Ñ\81Ñ\82Ñ\80аниÑ\86а|ги Ñ\81одÑ\80жи следниве $1 страници}} од вкупно $2.}}',
+'category-article-count' => '{{PLURAL:$2|Ð\9eваа каÑ\82егоÑ\80иÑ\98а Ñ\98а Ñ\81одÑ\80жи Ñ\81амо Ñ\81леднава Ñ\81Ñ\82Ñ\80аниÑ\86а:|Ð\92о каÑ\82егоÑ\80иÑ\98аÑ\82а Ñ\81е {{PLURAL:$1|Ñ\81одÑ\80жи Ñ\81леднава Ñ\81Ñ\82Ñ\80аниÑ\86а|Ñ\81одÑ\80жаÑ\82 следниве $1 страници}} од вкупно $2.}}',
'category-article-count-limited' => '{{PLURAL:$1|Следната страница е|Следните $1 страници се}} во оваа категорија.',
'category-file-count' => '{{PLURAL:$2|Оваа категорија ја содржи само следната податотека.|{{PLURAL:$1|Следната податотека е|Следните $1 податотеки се}} во оваа категорија, од вкупно $2.}}',
'category-file-count-limited' => '{{PLURAL:$1|Следнава податотека е|Следниве $1 податотеки се}} во оваа категорија.',
'protectedpagetext' => 'Оваа страница е заклучена за уредувања и други дејства.',
'viewsourcetext' => 'Можете да го погледнете и копирате кодот на оваа страница:',
'viewyourtext' => "Можете да го погледнете и копирате кодот на '''вашите уредувања''' на оваа страница:",
-'protectedinterface' => 'Оваа страница содржи текст од посредникот на софтверот на ова вики и е превентивно заштитена поради можна злоупотреба.
+'protectedinterface' => 'Оваа страница содржи текст од посредникот на програмот на ова вики и е превентивно заштитена поради можна злоупотреба.
За да додавате или менувате преводи на сите викија, појдете на [//translatewiki.net/wiki/Main_Page?uselang=mk translatewiki.net] - проектот за локализација на МедијаВики.',
-'editinginterface' => "'''Ð\9fÑ\80едÑ\83пÑ\80едÑ\83ваÑ\9aе:''' УÑ\80едÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а коÑ\98а е дел од коÑ\80иÑ\81ниÑ\87киоÑ\82 поÑ\81Ñ\80едник на Ð\9cедиÑ\98аÐ\92ики Ñ\81оÑ\84Ñ\82веÑ\80оÑ\82.
+'editinginterface' => "'''Ð\9fÑ\80едÑ\83пÑ\80едÑ\83ваÑ\9aе:''' УÑ\80едÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а коÑ\98а е дел од коÑ\80иÑ\81ниÑ\87киоÑ\82 поÑ\81Ñ\80едник на пÑ\80огÑ\80амоÑ\82 Ð\9cедиÑ\98аÐ\92ики.
Промените на оваа страница ќе предизвикаат промени во корисничкиот посредник кај другите корисници на ова вики.
За да додадете или измените превод на сите викија, појдете на [//translatewiki.net/wiki/Main_Page?setlang=mk translatewiki.net] - проектот за локализација на МедијаВики.",
'sqlhidden' => '(Барањето до SQL е скриено)',
'newuserlogpagetext' => 'Ова е дневник на регистрирани корисници.',
# User rights log
-'rightslog' => 'Ð\94невник на менÑ\83ваÑ\9aа на коÑ\80иÑ\81ниÑ\87ки права',
+'rightslog' => 'Ð\94невник на коÑ\80иÑ\81ниÑ\87киÑ\82е права',
'rightslogtext' => 'Ова е дневник на промени на кориснички права.',
# Associated actions - in the sentence "You do not have permission to X"
'statistics-users-active-desc' => 'Корисници кои имаат извршено некое дејство {{PLURAL:$1|претходниот ден|во претходните $1 дена}}',
'statistics-mostpopular' => 'Најпосетувани страници',
-'disambiguations' => 'Страници што водат до страници за појаснување',
+'disambiguations' => 'Страници што водат до појаснителни страници',
'disambiguationspage' => 'Template:Појаснување',
-'disambiguations-text' => "Следните страници имаат барем по една врска што води до '''страница за појаснување'''.
-Наместо тоа, може да имаат врска до посоодветната тема.<br />
-Една страница се смета за страница за појаснување ако го користи шаблонот што води од [[MediaWiki:Disambiguationspage]]",
+'disambiguations-text' => "Следните страници имаат барем по една врска што води до '''појаснителна страница'''.
+Наместо тоа, може да имаат врска до посоодветна страница.<br />
+Една страница се смета за појаснителна ако го користи шаблонот што води од [[MediaWiki:Disambiguationspage]]",
'pageswithprop' => 'Страници со својство',
'pageswithprop-legend' => 'Страници со својство',
'minutes' => '{{PLURAL:$1|$1 минута|$1 минути}}',
'hours' => '{{PLURAL:$1|$1 час|$1 часа}}',
'days' => '{{PLURAL:$1|$1 ден|$1 дена}}',
+'weeks' => '{{PLURAL:$1|$1 недела|$1 недели}}',
'months' => '{{PLURAL:$1|$1 месец|$1 месеци}}',
'years' => '{{PLURAL:$1|$1 година|$1 години}}',
'ago' => 'пред $1',
# New logging system
'logentry-delete-delete' => '$1 {{GENDER:$2|ја избриша}} страницата $3',
-'logentry-delete-restore' => '$1 {{GENDER:$2|ја врати}} страницата $3',
+'logentry-delete-restore' => '$1 {{GENDER:$2|Ñ\98а повÑ\80аÑ\82и}} Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а $3',
'logentry-delete-event' => '$1 {{GENDER:$2|ја измени}} видливоста на {{PLURAL:$5|настан во дневникот|$5 настани во дневникот}} на $3: $4',
'logentry-delete-revision' => '$1 {{GENDER:$2|ја измени}} видливоста на {{PLURAL:$5|ревизија|$5 ревизии}} на страницата $3: $4',
'logentry-delete-event-legacy' => '$1 {{GENDER:$2|ја измени}} видливоста на настаните во дневникот на $3',
# Image rotation
'rotate-comment' => 'Сликата е завртена за $1 {{PLURAL:$1|степен|степени}} вдесно',
+# Unknown messages
+'hours-ago' => 'пред $1 {{PLURAL:$1|час|часа}}',
+'minutes-ago' => 'пред $1 {{PLURAL:$1|минута|минути}}',
+'seconds-ago' => 'пред $1 {{PLURAL:$1|секунда|секунди}}',
);
'nov' => 'നവം.',
'dec' => 'ഡിസം.',
+'monday-at' => 'തിങ്കളാഴ്ച്ച $1-നു്',
+'tuesday-at' => 'ചൊവ്വാഴ്ച്ച $1-നു്',
+'wednesday-at' => 'ബുധനാഴ്ച്ച $1-നു്',
+'thursday-at' => 'വ്യാഴാഴ്ച്ച $1-നു്',
+'friday-at' => 'വെള്ളിയാഴ്ച്ച $1-നു്',
+'saturday-at' => 'ശനിയാഴ്ച്ച $1-നു്',
+'sunday-at' => 'ഞായറാഴ്ച്ച $1-നു്',
+'today-at' => 'ഇന്ന് $1-നു്',
+'yesterday-at' => 'ഇന്നലെ $1-നു്',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|വർഗ്ഗം|വർഗ്ഗങ്ങൾ}}',
'category_header' => '"$1" എന്ന വർഗ്ഗത്തിലെ താളുകൾ',
താത്കാലിക രഹസ്യവാക്ക്: $2',
'passwordreset-emailsent' => 'ഒരു രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയച്ചിട്ടുണ്ട്.',
'passwordreset-emailsent-capture' => 'രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയച്ചിട്ടുണ്ട്, അത് താഴെക്കൊടുക്കുന്നു.',
-'passwordreset-emailerror-capture' => 'താഴàµ\86à´\95àµ\8dà´\95àµ\8aà´\9fàµ\81à´¤àµ\8dതിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨, രഹസàµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´ªàµ\81നർസà´\9càµ\8dà´\9càµ\80à´\95à´°à´£ à´\87à´®àµ\86യിൽ à´¸àµ\83à´·àµ\8dà´\9fà´¿à´\95àµ\8dà´\95ാനായàµ\86à´\99àµ\8dà´\95à´¿à´²àµ\81à´\82, à´\89പയàµ\8bà´\95àµ\8dതാവിനàµ\8d à´\85യയàµ\8dà´\95àµ\8dà´\95ാൻ à´\95à´´à´¿à´\9eàµ\8dà´\9eà´¿à´²àµ\8dà´²: $1',
+'passwordreset-emailerror-capture' => 'താഴàµ\86à´\95àµ\8dà´\95àµ\8aà´\9fàµ\81à´¤àµ\8dതിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨, രഹസàµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´ªàµ\81നർസà´\9càµ\8dà´\9càµ\80à´\95à´°à´£ à´\87à´®àµ\86യിൽ à´¸àµ\83à´·àµ\8dà´\9fà´¿à´\95àµ\8dà´\95ാനായàµ\86à´\99àµ\8dà´\95à´¿à´²àµ\81à´\82, à´\85à´¤àµ\8d {{GENDER:$2|à´\89പയàµ\8bà´\95àµ\8dതാവിനàµ\8d}} à´\85യയàµ\8dà´\95àµ\8dà´\95àµ\81à´¨àµ\8dനതàµ\8d പരാà´\9cയപàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fàµ\81: $1',
# Special:ChangeEmail
'changeemail' => 'ഇമെയിൽ വിലാസത്തിൽ മാറ്റംവരുത്തുക',
'powersearch-togglenone' => 'ഒന്നുംവേണ്ട',
'search-external' => 'ബാഹ്യ അന്വേഷണം',
'searchdisabled' => '{{SITENAME}} സംരംഭത്തിൽ തിരച്ചിൽ ദുർബലപ്പെടുത്തിയിരിക്കുന്നു. താങ്കൾക്ക് ഗൂഗിൾ ഉപയോഗിച്ച് തത്കാലം തിരച്ചിൽ നടത്താവുന്നതാണ്. പക്ഷെ ഗൂഗിളിൽ {{SITENAME}} സംരംഭത്തിന്റെ സൂചിക കാലഹരണപ്പെട്ടതായിരിക്കാൻ സാദ്ധ്യതയുണ്ട്.',
+'search-error' => 'തിരയുന്നതിനിടെ ഒരു പിഴവുണ്ടായി: $1',
# Preferences page
'preferences' => 'ക്രമീകരണങ്ങൾ',
'proxyblocksuccess' => 'ചെയ്തു കഴിഞ്ഞു.',
'sorbsreason' => '{{SITENAME}} ഉപയോഗിക്കുന്ന DNSBL ൽ താങ്കളുടെ ഐ.പി. വിലാസം ഒരു ഓപ്പൺ പ്രോക്സിയായാണു രേഖപ്പെടുത്തിട്ടുള്ളത്.',
'sorbs_create_account_reason' => '{{SITENAME}} ഉപയോഗിക്കുന്ന DNSBL ൽ താങ്കളുടെ ഐ.പി. വിലാസം ഒരു ഓപ്പൺ പ്രോക്സിയായാണു രേഖപ്പെടുത്തിട്ടുള്ളത്. താങ്കൾക്ക് അംഗത്വമെടുക്കാൻ സാദ്ധ്യമല്ല.',
+'xffblockreason' => 'എക്സ്-ഫോർവേഡഡ്-ഫോർ ഹെഡറിലെ ഒരു ഐ.പി. വിലാസം, താങ്കളുടേതോ താങ്കൾ ഉപയോഗിക്കുന്ന പ്രോക്സി സെർവറിലേതോ ആകാം, തടയപ്പെട്ടിരിക്കുന്നതാണ്. തടയലിന്റെ കാരണം: $1',
'cant-block-while-blocked' => 'താങ്കൾ തടയപ്പെട്ടിരിക്കുമ്പോൾ മറ്റുപയോക്താക്കളെ തടയാൻ താങ്കൾക്ക് സാധിക്കില്ല.',
'cant-see-hidden-user' => 'താങ്കൾ തടയാൻ ശ്രമിക്കുന്ന ഉപയോക്താവ് മുമ്പേ തടയപ്പെടുകയും മറയ്ക്കപ്പെടുകയും ചെയ്യപ്പെട്ടതാണ്. താങ്കൾക്ക് ഉപയോക്താവിനെ മറയ്ക്കാനുള്ള അവകാശം ഇല്ലെങ്കിൽ, ഉപയോക്താവിനെതിരെ ഉള്ള തടയൽ കാണാനോ തിരുത്താനോ കഴിയുന്നതല്ല.',
'ipbblocked' => 'മറ്റുള്ളവരെ തടയാനോ അവരുടെ തടയൽ നീക്കാനോ താങ്കൾക്ക് കഴിയില്ല. കാരണം താങ്കൾ തന്നെ തടയപ്പെട്ടിരിക്കുകയാണ്',
'minutes' => '{{PLURAL:$1|ഒരു മിനിറ്റ്|$1 മിനിറ്റ്}}',
'hours' => '{{PLURAL:$1|ഒരു മണിക്കൂർ|$1 മണിക്കൂർ}}',
'days' => '{{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസം}}',
+'weeks' => '{{PLURAL:$1|ഒരാഴ്ച്ച|$1 ആഴ്ച്ച}}',
'months' => '{{PLURAL:$1|ഒരു മാസം|$1 മാസം}}',
'years' => '{{PLURAL:$1|ഒരു വർഷം|$1 വർഷം}}',
'ago' => '$1 മുമ്പ്',
# Image rotation
'rotate-comment' => 'ചിത്രം പ്രദക്ഷിണദിശയിൽ {{PLURAL:$1|ഒരു ഡിഗ്രി|$1 ഡിഗ്രി}} തിരിച്ചു',
+# Unknown messages
+'hours-ago' => '{{PLURAL:$1|ഒരു മണിക്കൂർ|$1 മണിക്കൂർ}} മുൻപ്',
+'minutes-ago' => '{{PLURAL:$1|ഒരു മിനിറ്റ്|$1 മിനിറ്റ്}} മുൻപ്',
+'seconds-ago' => '{{PLURAL:$1|ഒരു സെക്കന്റ്|$1 സെക്കന്റ്}} മുൻപ്',
);
'underline-always' => 'Altied',
'underline-never' => 'Nooit',
-'underline-default' => 'Standardinstelling',
+'underline-default' => 'Standard in joew vormgeving of webkieker',
# Font style option in Special:Preferences
'editfont-style' => 'Lettertype veur de tekste t bewarkingsveld:',
'nov' => 'nov',
'dec' => 'des',
+'today-at' => '$1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategorie|Kategorieën}}',
'category_header' => 'Artikels in kategorie $1',
'newwindow' => '(niej vienster)',
'cancel' => 'Aofbreken',
'moredotdotdot' => 'Meer...',
-'mypage' => 'Mien gebrukerszied',
+'morenotlisted' => 'Meer niet in de lieste...',
+'mypage' => 'Gebrukerszied',
'mytalk' => 'Mien overleg',
'anontalk' => 'Overlegzied veur dit IP-adres',
'navigation' => 'Navigasie',
'vector-action-protect' => 'Beveiligen',
'vector-action-undelete' => 'Weerummeplaotsen',
'vector-action-unprotect' => 'Beveiliging wiezigen',
-'vector-simplesearch-preference' => 'Verbeterde zeuksuggesties anzetten (allinnig mit Vector-vormgeving)',
+'vector-simplesearch-preference' => 'Vereenvoudigd zeuken anzetten (allinnig mit Vector-vormgeving)',
'vector-view-create' => 'Anmaken',
'vector-view-edit' => 'Bewarken',
'vector-view-history' => 'Geschiedenisse bekieken',
'namespaces' => 'Naamruumtes',
'variants' => 'Variaanten',
+'navigation-heading' => 'Navigasiemenu',
'errorpagetitle' => 'Foutmelding',
'returnto' => 'Weerumme naor $1.',
'tagline' => 'Van {{SITENAME}}',
'viewsource-title' => 'Bron bekieken van $1',
'actionthrottled' => 'Haandeling tegenehöllen',
'actionthrottledtext' => "As maotregel tegen t plaotsen van ongewunste verwiezingen, is t antal keren da'j disse haandeling in n korte tied uutvoeren kunnen beteund. Je hebben de limiet overschrejen. Probeer t over n antal minuten weer.",
-'protectedpagetext' => 'Disse zied is beveiligd um bewarkingen te veurkoemen.',
+'protectedpagetext' => 'Disse zied is beveiligd. Bewarken of aandere haandelingen bin niet meugelik.',
'viewsourcetext' => 'Je kunnen de brontekste van disse zied bewarken en bekieken:',
'viewyourtext' => "Je kunnen '''joew bewarkingen''' an de brontekste van disse zied bekieken en kopiëren:",
'protectedinterface' => "Op disse zied steet tekste die gebruukt wörden veur systeemteksten van disse wiki. Allinnig beheerders kunnen disse zied bewarken.
Je kunnen {{SITENAME}} noen anoniem gebruken of je eigen <span class='plainlinks'>[$1 opniej anmelden]</span> onder disse of n aandere gebrukersnaam.
t Kan ween dat der wat ziejen bin die weeregeven wörden asof je an-emeld bin totda'j t tussengeheugen van joew webkieker leegmaken.",
+'welcomeuser' => 'Welkom, $1!',
'yourname' => 'Gebrukersnaam',
+'userlogin-yourname' => 'Gebrukersnaam',
+'userlogin-yourname-ph' => 'Geef joew gebrukersnaam op',
'yourpassword' => 'Wachtwoord',
+'userlogin-yourpassword' => 'Wachtwoord',
+'userlogin-yourpassword-ph' => 'Geef joew wachtwoord op',
'yourpasswordagain' => 'Opniej invoeren',
'remembermypassword' => 'Vanzelf anmelden (hooguut $1 {{PLURAL:$1|dag|dagen}})',
+'userlogin-remembermypassword' => 'Vanzelf anmelden',
'securelogin-stick-https' => "Verbunnen blieven via HTTPS naoda'j an-emeld bin",
'yourdomainname' => 'Joew domein',
'password-change-forbidden' => 'Je kunnen joew wachtwoord niet wiezigen op disse wiki.',
'logout' => 'Aofmelden',
'userlogout' => 'Aofmelden',
'notloggedin' => 'Niet an-emeld',
+'userlogin-noaccount' => "He'j nog gien gebrukersnaam?",
+'userlogin-joinproject' => 'Over {{SITENAME}}',
'nologin' => "He'j nog gien gebrukersnaam? '''$1'''.",
'nologinlink' => 'Maak n gebrukersprofiel an',
'createaccount' => 'Niej gebrukersprofiel anmaken',
'gotaccount' => "Stao'j al in-eschreven? '''$1'''.",
'gotaccountlink' => 'Anmelden',
'userlogin-resetlink' => "Bi'j de anmeldgegevens kwiet?",
-'createaccountmail' => 'per netpost',
+'createaccountmail' => 'Gebruuk n tiejelik wachtwoord dat joe netzelde is en stuur t naor t netpostadres dat hieronder steet',
'createaccountreason' => 'Reden:',
'badretype' => "De wachtwoorden die'j in-etikt hebben bin niet liek alleens.",
'userexists' => 'Disse gebrukersnaam is al gebruuk.
'editwarning-warning' => "A'j disse zied aofsluten dan kan t ween dat der wieziging die'j emaakt hebben kwiet raken.
A'j an-emeld bin, dan ku'j disse waorschuwing uutzetten in t tabblad \"Bewarken\" in joew veurkeuren.",
+# Content models
+'content-model-wikitext' => 'wikitekste',
+'content-model-text' => 'tekste zonder opmaak',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
# Parser/template warnings
'expensive-parserfunction-warning' => 'Waorschuwing: disse zied gebruukt te veule kostbaore parserfunksies.
'search-interwiki-default' => '$1 resultaoten:',
'search-interwiki-more' => '(meer)',
'search-relatedarticle' => 'Verwaant',
-'mwsuggest-disable' => 'Anbevelingen via AJAX uutschakelen',
+'mwsuggest-disable' => 'Zeuksuggesties uutzetten',
'searcheverything-enable' => 'In alle naamruumten zeuken',
'searchrelated' => 'verwaant',
'searchall' => 'alles',
'prefs-emailconfirm-label' => 'Netpostbevestiging:',
'prefs-textboxsize' => 'Aofmetingen bewarkingsscharm',
'youremail' => 'Netpostadres (niet verplicht) *',
-'username' => 'Gebrukersnaam:',
-'uid' => 'Gebrukersnummer:',
+'username' => '{{GENDER:$1|Gebrukersnaam}}:',
+'uid' => '{{GENDER:$1|Gebrukersnummer}}:',
'prefs-memberingroups' => 'Lid van {{PLURAL:$1|groep|groepen}}:',
'prefs-registration' => 'Registrasiedaotum:',
'yourrealname' => 'Echte naam (niet verplicht)',
Feitelik mutten ze rechtstreeks verwiezen naor t juuste onderwarp.<br />
Ziejen wörden ezien as n deurverwieszied, as de mal gebruukt wörden die vermeld steet op [[MediaWiki:Disambiguationspage]].",
+'pageswithprop-submit' => 'Zeuk',
+
'doubleredirects' => 'Dubbele deurverwiezingen',
'doubleredirectstext' => 'Op disse lieste staon alle ziejen die deurverwiezen naor aandere deurverwiezingen.
Op elke regel steet de eerste en de tweede deurverwiezing, daorachter steet de doelzied van de tweede deurverwiezing.
'blanknamespace' => '(Heufdnaamruumte)',
# Contributions
-'contributions' => 'Biedragen van disse gebruker',
+'contributions' => '{{GENDER:$1|Biedragen van disse gebruker}}',
'contributions-title' => 'Biedragen van $1',
'mycontris' => 'Mien biedragen',
'contribsub2' => 'Veur $1 ($2)',
'pageinfo-magic-words' => '{{PLURAL:$1|Magies woord|Magiese woorden}} ($1)',
'pageinfo-hidden-categories' => 'Verbörgen {{PLURAL:$1|kategorie|kategorieën}} ($1)',
'pageinfo-templates' => '{{PLURAL:$1|Gebruukten mal|Gebruukten mallen}} ($1)',
+'pageinfo-toolboxlink' => 'Informasie over disse zied',
+'pageinfo-redirectsto' => 'Verwis deur naor',
+'pageinfo-redirectsto-info' => 'informasie',
+'pageinfo-contentpage' => 'Eteld as zied mit inhoud',
+'pageinfo-contentpage-yes' => 'Ja',
# Skin names
'skinname-cologneblue' => 'Keuls blauw',
'hours' => '{{PLURAL:$1|$1 ure|$1 uren}}',
'days' => '{{PLURAL:$1|$1 dag|$1 dagen}}',
'ago' => '$1 eleen',
+'just-now' => 'onderlest',
# Bad image list
'bad_image_list' => 'De opmaak is as volgt:
'htmlform-submit' => 'Opslaon',
'htmlform-reset' => 'Wiezigingen ongedaonmaken',
'htmlform-selectorother-other' => 'Aanders',
+'htmlform-no' => 'Nee',
+'htmlform-yes' => 'Ja',
# SQLite database support
'sqlite-has-fts' => 'Versie $1 mit ondersteuning veur "full-text" zeuken',
'nov' => 'nov',
'dec' => 'dec',
+'monday-at' => 'Maandag om $1',
+'tuesday-at' => 'Dinsdag om $1',
+'wednesday-at' => 'Woensdag om $1',
+'thursday-at' => 'Donderdag om $1',
+'friday-at' => 'Vrijdag om $1',
+'saturday-at' => 'Zaterdag om $1',
+'sunday-at' => 'Zondag om $1',
+'today-at' => '$1',
+'yesterday-at' => 'Gisteren om $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categorie|Categorieën}}',
'category_header' => 'Pagina’s in categorie "$1"',
# Image rotation
'rotate-comment' => 'Afbeelding gedraaid, $1 {{PLURAL:$1|graad|graden}} met de klok mee',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|uur}} geleden',
+'minutes-ago' => '$1 {{PLURAL:$1|minuut|minuten}} geleden',
+'seconds-ago' => '$1 {{PLURAL:$1|seconde|seconden}} geleden',
);
'duration-centuries' => '$1 {{PLURAL:$1|century|centuries}}',
'duration-millennia' => '$1 {{PLURAL:$1|millennium|millennia}}',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|ଘଣ୍ଟା}} ଆଗରୁ',
+'minutes-ago' => '$1 {{PLURAL:$1|ମିନିଟ|ମିନିଟ}} ଆଗରୁ',
+'seconds-ago' => '$1 {{PLURAL:$1|ସେକେଣ୍ଡ|ସେକେଣ୍ଡ}} ଆଗରୁ',
);
'tog-usenewrc' => 'ਹਾਲ ’ਚ ਹੋਏ ਬਦਲਾਵ ਅਤੇ ਧਿਆਨਸੂਚੀ ਵਿੱਚ ਪੰਨੇ ਮੁਤਾਬਕ ਬਦਲਾਵ ਦੇ ਗਰੁੱਪ ਬਣਾਓ (ਜਾਵਾਸਕ੍ਰਿਪਟ ਦੀ ਜਰੂਰਤ ਹੈ)',
'tog-numberheadings' => 'ਆਟੋ-ਨੰਬਰ ਹੈਡਿੰਗ',
'tog-showtoolbar' => 'ਸੋਧ ਟੂਲਬਾਰ ਵੇਖੋ (JavaScript ਚਾਹੀਦੀ ਹੈ)',
-'tog-editondblclick' => 'ਦà©\82ਹਰà©\87 à¨\95ਲਿੱà¨\95 â\80\99ਤà©\87 ਪੰਨà©\87 ਨà©\82à©° ਸੰਪਾਦਤ à¨\95ਰà©\8b (à¨\9cਾਵਾਸà¨\95à©\8dਰਿਪà¨\9f ਦà©\80 à¨\9cਰà©\82ਰਤ ਹੈ)',
-'tog-editsection' => '[ਸੰਪਾਦਨ] à¨\95à©\9cà©\80à¨\86à¨\82 ਦà©\81à¨\86ਰਾ à¨\85ਨà©\81à¨à¨¾à¨\97 ਸੰਪਾਦਨ ਸਮਰੱਥਾਵਾਨ à¨\95ਰà©\8b',
+'tog-editondblclick' => 'ਦà©\8b ਵਾਰ à¨\95ਲਿੱà¨\95 à¨\95ਰਨ ਨਾਲ ਸਫ਼à©\87 ਸà©\8bਧà©\8b (à¨\9cਾਵਾਸà¨\95à©\8dਰਿਪà¨\9f à¨\9aਾਹà©\80ਦà©\80 ਹੈ)',
+'tog-editsection' => '[ਸà©\8bਧ] ਲਿੰà¨\95 ਰਾਹà©\80à¨\82 à¨à¨¾à¨\97 ਸà©\8bਧ à¨\95ਰਨਾ à¨\9aਾਲà©\82',
'tog-editsectiononrightclick' => 'ਭਾਗ ਸਿਰਲੇਖਾਂ ਤੇ ਸੱਜੀ ਕਲਿੱਕ ਦੁਆਰਾ ਸੋਧ ਯੋਗ ਕਰੋ (ਜਾਵਾ ਸਕ੍ਰਿਪਟ ਲੋੜੀਂਦੀ ਹੈ)',
'tog-showtoc' => 'ਤਤਕਰਾ ਵੇਖਾਓ (3 ਤੋਂ ਵੱਧ ਸਿਰਲੇਖਾਂ ਵਾਲੇ ਪੰਨਿਆਂ ਲਈ)',
'tog-rememberpassword' => 'ਇਸ ਬਰਾਊਜ਼ਰ ਉੱਤੇ ਮੇਰਾ ਲਾਗਇਨ ਯਾਦ ਰੱਖੋ ($1 {{PLURAL:$1|ਦਿਨ|ਦਿਨਾਂ}} ਲਈ ਵੱਧ ਤੋਂ ਵੱਧ)',
'vector-action-unprotect' => 'ਸੁਰੱਖਿਆ ਬਦਲੋ',
'vector-simplesearch-preference' => 'ਸਧਾਰਨ ਖੋਜ ਸਲਾਹ ਪੱਟੀ ਯੋਗ ਕਰੋ (ਸਿਰਫ਼ ਵਿਕਟਰ ਸਕਿੰਨ ਵਿਚ)',
'vector-view-create' => 'ਬਣਾਓ',
-'vector-view-edit' => 'ਸੰਪਾਦਨ',
-'vector-view-history' => 'à¨\87ਤਿਹਾਸ ਵੇਖੋ',
+'vector-view-edit' => 'ਸà©\8bਧ',
+'vector-view-history' => 'à¨\85ਤà©\80ਤ ਵੇਖੋ',
'vector-view-view' => 'ਪੜ੍ਹੋ',
'vector-view-viewsource' => 'ਸਰੋਤ ਵੇਖੋ',
'actions' => 'ਕਾਰਵਾਈਆਂ',
'searchbutton' => 'ਖੋਜ',
'go' => 'ਜਾਓ',
'searcharticle' => 'ਜਾਓ',
-'history' => 'ਪੰਨà©\87 ਦਾ à¨\87ਤਿਹਾਸ',
-'history_short' => 'à¨\87ਤਿਹਾਸ',
+'history' => 'ਸਫ਼ਾ à¨\85ਤà©\80ਤ',
+'history_short' => 'à¨\85ਤà©\80ਤ',
'updatedmarker' => 'ਮੇਰੀ ਆਖਰੀ ਫੇਰੀ ਤੋਂ ਬਾਅਦ ਦੇ ਅੱਪਡੇਟ',
'printableversion' => 'ਛਪਣਯੋਗ ਵਰਜਨ',
'permalink' => 'ਪੱਕਾ ਲਿੰਕ',
'print' => 'ਛਾਪੋ',
'view' => 'ਵੇਖੋ',
-'edit' => 'ਸੰਪਾਦਨ',
+'edit' => 'ਸà©\8bਧ',
'create' => 'ਬਣਾਓ',
'editthispage' => 'ਇਹ ਸਫ਼ਾ ਸੋਧੋ',
'create-this-page' => 'ਇਹ ਸਫ਼ਾ ਬਣਾਓ',
'otherlanguages' => 'ਹੋਰ ਭਾਸ਼ਾਵਾਂ ਵਿੱਚ',
'redirectedfrom' => '($1 ਤੋਂ ਰੀਡਿਰੈਕਟ)',
'redirectpagesub' => 'ਰੀਡਿਰੈਕਟ ਸਫ਼ਾ',
-'lastmodifiedat' => 'à¨\87ਸ ਪੰਨਾ ਦਾ ਪਿੱà¨\9bਲਾ ਬਦਲਾà¨\85 $1 ਨà©\82à©° $2 ਵà¨\9cà©\87 ਹà©\8bà¨\87à¨\86 ਸà©\80।',
+'lastmodifiedat' => 'à¨\87ਹ ਸਫ਼à©\87 ਵਿੱà¨\9a à¨\86à¨\96ਰà©\80 ਸà©\8bਧ $1 ਨà©\82à©° $2 ਵà¨\9cà©\87 ਹà©\8bà¨\88।',
'viewcount' => 'ਇਹ ਸਫ਼ਾ {{PLURAL:$1|ਇੱਕ ਵਾਰ|$1 ਵਾਰ}} ਵੇਖਿਆ ਗਿਆ।',
'protectedpage' => 'ਸੁਰੱਖਿਅਤ ਪੇਜ',
'jumpto' => 'ਇਸ ’ਤੇ ਜਾਓ:',
'mainpage' => 'ਮੁੱਖ ਸਫ਼ਾ',
'mainpage-description' => 'ਮੁੱਖ ਸਫ਼ਾ',
'policy-url' => 'Project:ਨੀਤੀ',
-'portal' => 'ਸਮਾà¨\9c ਮà©\81ੱà¨\96 ਪੰਨਾ',
+'portal' => 'ਸਮਾà¨\9c ਸੱਥ',
'portal-url' => 'Project:ਸਮਾਜ ਸੱਥ',
'privacy' => 'ਪਰਾਈਵੇਸੀ ਨੀਤੀ',
'privacypage' => 'Project:ਪਰਾਈਵੇਸੀ ਨੀਤੀ',
'newpages-username' => 'ਯੂਜ਼ਰ-ਨਾਂ:',
'ancientpages' => 'ਸਭ ਤੋਂ ਪੁਰਾਣੇ ਪੇਜ',
'move' => 'ਸਥਾਨਾਂਤਰਨ',
-'movethispage' => 'à¨\87ਹ ਪà©\87à¨\9c ਭੇਜੋ',
+'movethispage' => 'à¨\87ਹ ਸਫ਼ਾ ਭੇਜੋ',
'unusedcategoriestext' => 'ਇਹ ਕੈਟੇਗਰੀ ਸਫ਼ੇ ਮੌਜੂਦ ਹਨ ਹਾਲਾਂਕਿ ਕਿਸੇ ਵੀ ਸਫ਼ੇ ਜਾਂ ਕੈਟੇਗਰੀ ਨੇ ਇਹਨਾਂ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕੀਤੀ।',
'notargettitle' => 'ਟਾਰਗੇਟ ਨਹੀਂ',
'pager-newer-n' => '{{PLURAL:$1|1 ਨਵਾਂ|$1 ਨਵੇਂ}}',
# Watchlist
'watchlist' => 'ਨਿਗਰਾਨ-ਸੂਚੀ',
-'mywatchlist' => 'ਧਿà¨\86ਨਸੂਚੀ',
+'mywatchlist' => 'ਨਿà¨\97ਰਾਨ-ਸੂਚੀ',
'watchlistfor2' => '$1 $2 ਲਈ',
'nowatchlist' => 'ਤੁਹਾਡੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿਚ ਕੋਈ ਚੀਜ਼ ਨਹੀਂ ਹੈ।',
'watchlistanontext' => 'ਆਪਣੀ ਨਿਗਰਾਨੀ-ਲਿਸਟ ਵਿਚਲੀਆਂ ਚੀਜ਼ਾਂ ਵੇਖਣ ਜਾਂ ਸੋਧਣ ਲਈ ਮਿਹਰਬਾਨੀ ਕਰਕੇ $1।',
'wlnote' => "$3, $4 ਮੁਤਾਬਕ ਆਖ਼ਰੀ {{PLURAL:$2|ਘੰਟੇ|'''$2''' ਘੰਟਿਆਂ}} ਵਿਚ {{PLURAL:
$1|ਤਬਦੀਲੀ ਹੋਈ|'''$1''' ਤਬਦੀਲੀਆਂ ਹੋਈਆਂ}}, ਹੇਠਾਂ ਵੇਖੋ।",
'wlshowlast' => 'ਪਿੱਛਲੇ $1 ਘੰਟੇ $2 ਦਿਨ $3 ਵੇਖੋ',
-'watchlist-options' => 'ਧਿà¨\86ਨਸà©\82à¨\9aà©\80 ਵਿà¨\95ਲਪ',
+'watchlist-options' => 'ਨਿà¨\97ਰਾਨ-ਸà©\82à¨\9aà©\80 à¨\9aà©\8bਣਾà¨\82',
# Displayed when you click the "watch" button and it is in the process of watching
'watching' => 'ਨਿਗ੍ਹਾ (ਵਾਚ) ਰੱਖੀ ਜਾ ਰਹੀ ਹੈ...',
'nov' => 'lis',
'dec' => 'gru',
+'monday-at' => 'poniedziałek, $1',
+'tuesday-at' => 'wtorek, $1',
+'wednesday-at' => 'środa, $1',
+'thursday-at' => 'czwartek, $1',
+'friday-at' => 'piątek, $1',
+'saturday-at' => 'sobota, $1',
+'sunday-at' => 'niedziela, $1',
+'today-at' => '$1',
+'yesterday-at' => 'wczoraj, $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategoria|Kategorie}}',
'category_header' => 'Strony w kategorii „$1”',
'minutes' => '{{PLURAL:$1|$1 minuta|$1 minuty|$1 minut}}',
'hours' => '{{PLURAL:$1|$1 godzina|$1 godziny|$1 godzin}}',
'days' => '{{PLURAL:$1|$1 dzień|$1 dni}}',
+'weeks' => '{{PLURAL:$1|$1 tydzień|$1 tygodnie|$1 tygodni}}',
'months' => '{{PLURAL:$1|$1 miesiąc|$1 miesiące|$1 miesięcy}}',
'years' => '{{PLURAL:$1|$1 rok|$1 lata|$1 lat}}',
'ago' => '$1 temu',
# Image rotation
'rotate-comment' => 'Obraz został odwrócony o $1 {{PLURAL:$1|stopień|stopnie|stopni}} (w kierunku zgodnym z ruchem wskazówek zegara)',
+# Unknown messages
+'hours-ago' => '{{PLURAL:$1|przed godziną|$1 godziny temu|$1 godzin temu}}',
+'minutes-ago' => '{{PLURAL:$1|przed minutą|$1 minuty temu|$1 minut temu}}',
+'seconds-ago' => '{{PLURAL:$1|przed sekundą|$1 sekundy temu|$1 sekund temu}}',
);
# Dates
'sunday' => 'dumìnica',
-'monday' => 'Lùn-es',
-'tuesday' => 'Màrtes',
-'wednesday' => 'Merco',
-'thursday' => 'Giòbia',
+'monday' => 'lùn-es',
+'tuesday' => 'màrtes',
+'wednesday' => 'merco',
+'thursday' => 'giòbia',
'friday' => 'Vënner',
'saturday' => 'Saba',
'sun' => 'Dum',
'nov' => 'Abbreviation of November, the eleventh month of the Gregorian calendar',
'dec' => 'Abbreviation of December, the twelfth month of the Gregorian calendar',
+'monday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Monday. $1 is the time.',
+'tuesday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Tuesday. $1 is the time.',
+'wednesday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Wednesday. $1 is the time.',
+'thursday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Thursday. $1 is the time.',
+'friday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Friday. $1 is the time.',
+'saturday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Saturday. $1 is the time.',
+'sunday-at' => 'Phrase for indicating that something occurred at a particular time on the most recent Sunday. $1 is the time.',
+'today-at' => 'Phrase for indicating that something occurred at a particular time today. $1 is the time.',
+'yesterday-at' => 'Phrase for indicating that something occurred at a particular time yesterday. $1 is the time.',
+
# Categories related messages
'pagecategories' => 'Used in the categories section of pages. Is followed by a colon and a list of categories.',
'category_header' => 'In category description page',
'userlogin-yourname' => 'In new vertical user login & create account forms, label for username field.
{{Identical|Username}}',
'userlogin-yourname-ph' => 'Placeholder text in new userlogin/create account form field.',
+'createacct-helpusername-url' => 'The URL of a page providing username guidance for the wiki.',
+'createacct-helpusername-link' => 'Message in new create account form providing guidance for username.',
'yourpassword' => 'In user preferences
{{Identical|Password}}',
'userlogin-yourpassword' => 'In new vertical user login & create account forms, label for password field.
{{Identical|Password}}',
'userlogin-yourpassword-ph' => 'Placeholder text in new userlogin form for password field.',
+'createacct-yourpassword-ph' => 'Placeholder text in new create account form for password field.',
'yourpasswordagain' => 'In user preferences',
+'createacct-yourpasswordagain' => 'In new create account form, label for field to re-enter password',
+'createacct-yourpasswordagain-ph' => 'Placeholder text in new create account form for re-enter password field.',
'remembermypassword' => 'A check box in [[Special:UserLogin]]
{{Identical|Remember my login on this computer}}',
See also:
* {{msg-mw|Helplogin-url}}',
+'createacct-join' => 'Subheading of vertical-layout create account form encouraging user to join the wiki.',
+'createacct-emailrequired' => 'Label in vertical-layout create account form for email field when it is required.',
+'createacct-emailoptional' => 'Label in vertical-layout create account form for email field when it is optional.',
+'createacct-email-ph' => 'Placeholder in vertical-layout create account form for email field.',
'createaccountmail' => 'Button text for creating a new account and sending the new password to the specified e-mail address directly, as used on [[Special:UserLogin/signup]] if creating accounts by e-mail is allowed.',
+'createacct-realname' => 'In vertical-layout create account form, label for field to enter optional real name.',
'createaccountreason' => '{{Identical|Reason}}',
+'createacct-reason' => 'In vertical-layout create account form, label for field to enter reason to create an account when already logged-in.',
+'createacct-captcha' => 'Label in vertical-layout create account form for CAPTCHA input field when repositioned by JavaScript.',
+'createacct-captcha-help-url' => 'The URL of a page providing CAPTCHA assistance for the wiki.',
+'createacct-imgcaptcha-help' => 'Help text in vertical-layout create account form for image CAPTCHA input field when repositioned by JavaScript.',
+'createacct-imgcaptcha-ph' => 'Placehodler text in vertical-layout create account form for image CAPTCHA input field when repositioned by JavaScript.',
+'createacct-benefit-heading' => 'In vertical-layout create account form, the heading for the section describing the benefits of creating an account.',
+'createacct-benefit-icon1' => 'In vertical-layout create account form, the CSS style for the div next to the first benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head1' => 'In vertical-layout create account form, the text in the heading for the first benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body1' => 'In vertical-layout create account form, the text for the first benefit.',
+'createacct-benefit-icon2' => 'In vertical-layout create account form, the CSS style for the div next to the second benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head2' => 'In vertical-layout create account form, the text in the heading for the second benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body2' => 'In vertical-layout create account form, the text for the second benefit.',
+'createacct-benefit-icon3' => 'In vertical-layout create account form, the CSS style for the div next to the third benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head3' => 'In vertical-layout create account form, the text in the heading for the third benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body3' => 'In vertical-layout create account form, the text for the third benefit.',
'badretype' => 'Used as error message when the new password and its retype do not match.',
'userexists' => 'Used as error message in creating a user account.',
'loginerror' => 'Used as title of error message.
Parameters:
* $1 is a user name. This parameter can be used with GENDER.',
-'noemailcreate' => 'Used as error message in [[Special:UserLogin]].',
+'noemailcreate' => 'Used as error message when one user creates an account for another and there is no email.',
'passwordsent' => '* $1 - username',
'blocked-mailpassword' => 'Used as error message in password recovery.',
'eauthentsent' => "This message appears after entering an e-mail address in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}, then clicking on '{{int:saveprefs}}'.",
'resetprefs' => 'Button for resetting changes in the preferences page.',
'restoreprefs' => 'Used in [[Special:Preferences]]',
'prefs-editing' => 'Title of a tab in [[Special:Preferences]].
-When changing this message, please also update {{msg-mw|vector-editwarning-warning}} which references to this message.',
+When changing this message, please also update {{msg-mw|vector-editwarning-warning}} which references to this message.
+{{Identical|Editing}}',
'prefs-edit-boxsize' => 'Used on [[Special:Preferences]].',
'rows' => 'Used on [[Special:Preferences]], "Editing" section in the "Size of editing window" fieldset',
'columns' => 'Used on [[Special:Preferences]], "Editing" section in the "Size of editing window" fieldset',
* $1 - file title
See also:
* {{msg-mw|Filedelete-intro}}',
-'filedelete-legend' => '{{Identical|Delete}}',
+'filedelete-legend' => 'Used as fieldset label in the "Delete file" form.
+{{Identical|Delete file}}',
'filedelete-intro' => 'Used as introduction for FileDelete form.
See also:
* {{msg-mw|Filedelete|page title}}',
'contribsub2' => 'Contributions for "user" (links)
{{Identical|For $1}}',
'nocontribs' => 'Optional parameter: $1 is the user name',
-'uctop' => 'This message is used in [[Special:Contributions]]. It is used to show that a particular edit was the last made to a page. Example: 09:57, 11 February 2008 (hist) (diff) Pagename (edit summary) (top)',
+'uctop' => 'This message is used in [[Special:Contributions]]. It is used to show that a particular edit was the last made to a page. Example: 09:57, 11 February 2008 (hist) (diff) Pagename (edit summary) (top)
+{{Identical|Top}}',
'month' => 'Used in [[Special:Contributions]] and history pages ([{{fullurl:Sandbox|action=history}} example]), as label for a dropdown box to select a specific month to view the edits made in that month, and the earlier months. See also {{msg-mw|year}}.',
'year' => 'Used in [[Special:Contributions]] and history pages ([{{fullurl:Sandbox|action=history}} example]), as label for an input box to select a specific year to view the edits made in that year, and the earlier years.
This contains how the information in the picture is stored. This is most commonly Y, Cr, Cb to specify luma, red, blue. RGB is also possible to specify Red, Green, Blue.
{{Related|Exif-componentsconfiguration}}',
'exif-compressedbitsperpixel' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
-'exif-pixelydimension' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
+'exif-pixelydimension' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
+{{Identical|Image width}}',
'exif-pixelxdimension' => 'Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].',
'exif-usercomment' => "Exif is a format for storing metadata in image files. See this [[w:Exchangeable_image_file_format|Wikipedia article]] and the example at the bottom of [[commons:File:Phalacrocorax-auritus-020.jpg|this page on Commons]]. The tags are explained [http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html briefly] and [http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf in further detail].
# Image rotation
'rotate-comment' => 'Edit summary for the act of rotating an image.',
+# Unknown messages
+'hours-ago' => 'Phrase for indicating that something occurred a certain number of hours ago',
+'minutes-ago' => 'Phrase for indicating that something occurred a certain number of minutes ago',
+'seconds-ago' => 'Phrase for indicating that something occurred a certain number of seconds ago',
);
'nov' => 'nov',
'dec' => 'dec',
+'monday-at' => 'Luni, la $1',
+'tuesday-at' => 'Marți, la $1',
+'wednesday-at' => 'Miercuri, la $1',
+'thursday-at' => 'Joi,la $1',
+'friday-at' => 'Vineri, la $1',
+'saturday-at' => 'Sâmbătă, la $1',
+'sunday-at' => 'Duminică, la $1',
+'today-at' => '$1',
+'yesterday-at' => 'Ieri, la $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categorie|Categorii}}',
'category_header' => 'Pagini din categoria „$1”',
# Image rotation
'rotate-comment' => 'Imagine rotită în sensul acelor de ceasornic cu $1 {{PLURAL:$1|grad|grade|de grade}}',
+# Unknown messages
+'hours-ago' => 'acum $1 {{PLURAL:$1|oră|ore|de ore}}',
+'minutes-ago' => 'acum $1 {{PLURAL:$1|minut|minute|de minute}}',
+'seconds-ago' => 'acum {{PLURAL:$1|o secundă|$1 secunde|$1 de secunde}}',
);
'nov' => 'Nov',
'dec' => 'Dec',
+'monday-at' => 'Lunedìe a le $1',
+'tuesday-at' => 'Martedìe a le $1',
+'wednesday-at' => 'Mercrudìe a le $1',
+'thursday-at' => 'Sciuvedìe a le $1',
+'friday-at' => 'Venerdìe a le $1',
+'saturday-at' => 'Sabbète a le $1',
+'sunday-at' => 'Dumeneche a le $1',
+'today-at' => '$1',
+'yesterday-at' => 'Aijere a le $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Categorije|Categorije}}',
'category_header' => 'Pàggene jndr\'à categorie "$1"',
'minutes' => '{{PLURAL:$1|$1 minute|$1 minute}}',
'hours' => '{{PLURAL: $1|$1ore|$1 ore}}',
'days' => '{{PLURAL: $1|$1 sciurne|$1 sciurne}}',
+'weeks' => '{{PLURAL:$1|$1 sumàne}}',
'months' => '{{PLURAL:$1|$1 mese|$1 mise}}',
'years' => '{{PLURAL:$1|$1 anne}}',
'ago' => '$1 fà',
# Image rotation
'rotate-comment' => 'Immaggine rotate de $1 {{PLURAL:$1|grade}} in sienze orarie',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|ore}} fà',
+'minutes-ago' => '$1 {{PLURAL:$1|minute}} fà',
+'seconds-ago' => '$1 {{PLURAL:$1|seconde}} fà',
);
'nov' => 'nov',
'dec' => 'dec',
+'monday-at' => 'v pondelok o $1',
+'tuesday-at' => 'v utorok o $1',
+'wednesday-at' => 'v stredu o $1',
+'thursday-at' => 'vo štvrtok o $1',
+'friday-at' => 'v piatok o $1',
+'saturday-at' => 'v sobotu o $1',
+'sunday-at' => 'v nedeľu o $1',
+'today-at' => '$1',
+'yesterday-at' => 'včera o $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategória|Kategórie|Kategórie}}',
'category_header' => 'Stránky v kategórii „$1“',
# Image rotation
'rotate-comment' => 'Obrázok otočený o $1 {{PLURAL:$1|stupeň|stupne|stupňov}} v smere hodinových ručičiek',
+# Unknown messages
+'hours-ago' => 'pred $1 {{PLURAL:$1|hodinou|hodinami}}',
+'minutes-ago' => 'pred $1 {{PLURAL:$1|minútou|minútami}}',
+'seconds-ago' => 'pred $1 {{PLURAL:$1|sekundou|sekundami}}',
);
'nov' => 'nov.',
'dec' => 'dec.',
+'monday-at' => 'Ponedeljek ob $1',
+'tuesday-at' => 'Torek ob $1',
+'wednesday-at' => 'Sreda ob $1',
+'thursday-at' => 'Četrtek ob $1',
+'friday-at' => 'Petek ob $1',
+'saturday-at' => 'Sobota ob $1',
+'sunday-at' => 'Nedelja ob $1',
+'today-at' => '$1',
+'yesterday-at' => 'Včeraj ob $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategorija|Kategoriji|Kategorije}}',
'category_header' => 'Strani v kategoriji »$1«',
Začasno geslo: $2',
'passwordreset-emailsent' => 'Poslali smo e-pošto za postavitev gesla.',
'passwordreset-emailsent-capture' => 'Poslali smo e-pošto za ponastavitev gesla, ki je prikazana spodaj.',
-'passwordreset-emailerror-capture' => 'Ustvarili smo e-pošto za ponastavitev gesla, ki je prikazana spodaj, vendar pa pošiljanje uporabniku ni uspelo: $1',
+'passwordreset-emailerror-capture' => 'Ustvarili smo e-pošto za ponastavitev gesla, ki je prikazana spodaj, vendar pa pošiljanje {{GENDER:$2|uporabniku|uporabnici}} ni uspelo: $1',
# Special:ChangeEmail
'changeemail' => 'Sprememba e-poštnega naslova',
'minutes' => '$1 {{PLURAL:$1|minuta|minuti|minute|minut}}',
'hours' => '$1 {{PLURAL:$1|ura|uri|ure|ur}}',
'days' => '$1 {{PLURAL:$1|dan|dneva|dnevi|dni}}',
+'weeks' => '$1 {{PLURAL:$1|teden|tedna|tedni|tednov}}',
'months' => '$1 {{PLURAL:$1|mesec|meseca|mesece|mesecev}}',
'years' => '$1 {{PLURAL:$1|leto|leti|leta|let}}',
'ago' => 'pred $1',
# Image rotation
'rotate-comment' => 'Slika zavrti s $1 {{PLURAL:$1| degree|degrees}} v smeri urinega kazalca',
+# Unknown messages
+'hours-ago' => 'pred $1 {{PLURAL:$1|uro|urama|urami}}',
+'minutes-ago' => 'pred $1 {{PLURAL:$1|minuto|minutama|minutami}}',
+'seconds-ago' => 'pred $1 {{PLURAL:$1|sekundo|sekundama|sekundami}}',
);
'nov' => 'Kas',
'dec' => 'Ara',
+'monday-at' => '$1 Pazartesi günü',
+'tuesday-at' => '$1 Salı günü',
+'wednesday-at' => '$1 Çarşamba günü',
+'thursday-at' => '$1 Perşembe günü',
+'friday-at' => '$1 Cuma günü',
+'saturday-at' => '$1 Cumartesi günü',
+'sunday-at' => '$1 Pazar günü',
+'today-at' => '$1',
+'yesterday-at' => '$1 dün itibariyle',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Kategori|Kategoriler}}',
'category_header' => '"$1" kategorisindeki sayfalar',
'duration-centuries' => '$1 {{PLURAL:$1|yüzyıl|yüzyıl}}',
'duration-millennia' => '$1 {{PLURAL:$1|bin yıl|bin yıl}}',
+# Unknown messages
+'hours-ago' => '$1 {{PLURAL:$1|saat|saat}} önce',
+'minutes-ago' => '$1 {{PLURAL:$1|dakika|dakika}} önce',
+'seconds-ago' => '$1 {{PLURAL:$1|saniye|saniye}} önce',
);
* @author RLuts
* @author Riwnodennyk
* @author Sodmy
+ * @author Ua2004
* @author Urhixidur
* @author VolodymyrF
* @author Vox
'addedwatchtext' => "Сторінку «[[:$1]]» додано до вашого [[Special:Watchlist|списку спостереження]].
Подальші редагування цієї сторінки (та пов'язаної з нею сторінки обговорення) відображатимуться в цьому списку.",
'removewatch' => 'Видалити зі списку спостереження',
-'removedwatchtext' => 'Сторінка «[[:$1]]» вилучена з вашого [[Special:Watchlist|списку спостереження]].',
+'removedwatchtext' => 'Сторінку «[[:$1]]» вилучено з вашого [[Special:Watchlist|списку спостереження]].',
'watch' => 'Спостерігати',
'watchthispage' => 'Спостерігати за цією сторінкою',
'unwatch' => 'Скас. спостереження',
'nov' => 'tháng 11',
'dec' => 'tháng 12',
+'monday-at' => 'Thứ Hai lúc $1',
+'tuesday-at' => 'Thứ Ba lúc $1',
+'wednesday-at' => 'Thứ Tư lúc $1',
+'thursday-at' => 'Thứ Năm lúc $1',
+'friday-at' => 'Thứ Sáu lúc $1',
+'saturday-at' => 'Thứ Bảy lúc $1',
+'sunday-at' => 'Chủ Nhật lúc $1',
+'today-at' => '$1',
+'yesterday-at' => 'Hôm qua lúc $1',
+
# Categories related messages
'pagecategories' => '{{PLURAL:$1|Thể loại|Thể loại}}',
'category_header' => 'Các trang trong thể loại “$1”',
'minutes' => '$1 phút',
'hours' => '$1 giờ',
'days' => '$1 ngày',
+'weeks' => '{{PLURAL:$1|$1 tuần}}',
'months' => '$1 tháng',
'years' => '$1 năm',
'ago' => 'cách đây $1',
# Image rotation
'rotate-comment' => 'Đã quay hình $1 độ theo chiều kim đồng hồ',
+# Unknown messages
+'hours-ago' => 'Cách đây $1 {{PLURAL:$1|giờ}}',
+'minutes-ago' => 'Cách đây $1 {{PLURAL:$1|phút}}',
+'seconds-ago' => 'Cách đây $1 {{PLURAL:$1|giây}}',
);
'nov' => '11月',
'dec' => '12月',
+'monday-at' => '於星期一$1',
+'tuesday-at' => '於星期二$1',
+'wednesday-at' => '於星期三$1',
+'thursday-at' => '於星期四$1',
+'friday-at' => '於星期五$1',
+'saturday-at' => '於星期六$1',
+'sunday-at' => '於星期日$1',
+'today-at' => '$1',
+'yesterday-at' => '昨天$1',
+
# Categories related messages
'pagecategories' => '$1個分類',
'category_header' => '「$1」分類中的頁面',
'minutes' => '$1分鍾',
'hours' => '$1小時',
'days' => '$1天',
+'weeks' => '{{PLURAL:$1|$1周|$1周}}',
'months' => '{{PLURAL:$1|$1個月|$1個月}}',
'years' => '{{PLURAL:$1|$1年|$1年}}',
'ago' => '$1前',
# Image rotation
'rotate-comment' => '順時針旋轉圖像$1{{PLURAL:$1|度|度}}',
+# Unknown messages
+'hours-ago' => '$1小時前',
+'minutes-ago' => '$1分鐘前',
+'seconds-ago' => '$1秒前',
);
"}}",
"{{INT:googlesearch|",
"}}",
+ "{{ROOTPAGENAME}}",
"{{BASEPAGENAME}}",
"{{CONTENTLANGUAGE}}",
"{{PAGESINNAMESPACE:}}",
'ipb-default-expiry',
'pageinfo-header',
'pageinfo-footer',
+ 'createacct-benefit-head1',
+ 'createacct-benefit-icon1',
+ 'createacct-benefit-head2',
+ 'createacct-benefit-icon2',
+ 'createacct-benefit-head3',
+ 'createacct-benefit-icon3',
);
/** Optional messages, which may be translated only if changed in the target language. */
'yourname',
'userlogin-yourname',
'userlogin-yourname-ph',
+ 'createacct-helpusername-url',
+ 'createacct-helpusername-link',
'yourpassword',
'userlogin-yourpassword',
'userlogin-yourpassword-ph',
+ 'createacct-yourpassword-ph',
'yourpasswordagain',
+ 'createacct-yourpasswordagain',
+ 'createacct-yourpasswordagain-ph',
'remembermypassword',
'userlogin-remembermypassword',
'userlogin-signwithsecure',
'userlogin-resetlink',
'helplogin-url',
'userlogin-helplink',
+ 'createacct-join',
+ 'createacct-emailrequired',
+ 'createacct-emailoptional',
+ 'createacct-email-ph',
'createaccountmail',
+ 'createacct-realname',
'createaccountreason',
+ 'createacct-reason',
+ 'createacct-captcha',
+ 'createacct-captcha-help-url',
+ 'createacct-imgcaptcha-help',
+ 'createacct-imgcaptcha-ph',
+ 'createacct-benefit-heading',
+ 'createacct-benefit-icon1',
+ 'createacct-benefit-head1',
+ 'createacct-benefit-body1',
+ 'createacct-benefit-icon2',
+ 'createacct-benefit-head2',
+ 'createacct-benefit-body2',
+ 'createacct-benefit-icon3',
+ 'createacct-benefit-head3',
+ 'createacct-benefit-body3',
'badretype',
'userexists',
'loginerror',
job_namespace NUMBER DEFAULT 0 NOT NULL,
job_title VARCHAR2(255) NOT NULL,
job_timestamp TIMESTAMP(6) WITH TIME ZONE NULL,
- job_params CLOB NOT NULL
- job_random NUMBER NOT NULL default 0,
+ job_params CLOB NOT NULL,
+ job_random NUMBER DEFAULT 0 NOT NULL,
job_token VARCHAR2(32),
job_token_timestamp TIMESTAMP(6) WITH TIME ZONE,
job_sha1 VARCHAR2(32),
- job_attempts NUMBER NOT NULL default 0
+ job_attempts NUMBER DEFAULT 0 NOT NULL
);
ALTER TABLE &mw_prefix.job ADD CONSTRAINT &mw_prefix.job_pk PRIMARY KEY (job_id);
CREATE INDEX &mw_prefix.job_i01 ON &mw_prefix.job (job_cmd, job_namespace, job_title);
si_type VARCHAR2(32) NOT NULL,
si_key VARCHAR2(32) NOT NULL
);
-CREATE UNIQUE INDEX &mw_prefix.site_identifiers_u01 ON &mw_prefix.sites (si_type, si_key);
+CREATE UNIQUE INDEX &mw_prefix.site_identifiers_u01 ON &mw_prefix.site_identifiers (si_type, si_key);
CREATE INDEX &mw_prefix.site_identifiers_i01 ON &mw_prefix.site_identifiers (si_site);
CREATE INDEX &mw_prefix.site_identifiers_i02 ON &mw_prefix.site_identifiers (si_key);
function importRevision( &$revision, &$importer ) {
$id = $revision->getID();
- $text = $revision->getText();
+ $content = $revision->getContent( Revision::RAW );
+ $id = $id ? $id : '';
+
+ if ( $content === null ) {
+ echo "Revision $id is broken, we have no content available\n";
+ return;
+ }
+
+ $text = $content->serialize();
if ( $text === '' ) {
// This is what happens if the revision was broken at the time the
// dump was made. Unfortunately, it also happens if the revision was
// legitimately blank, so there's no way to tell the difference. To
// be safe, we'll skip it and leave it broken
- $id = $id ? $id : '';
+
echo "Revision $id is blank in the dump, may have been broken before export\n";
return;
}
),
'position' => 'top',
),
+ 'mediawiki.special.createaccount.vform' => array(
+ 'styles' => array(
+ 'resources/mediawiki.special/mediawiki.special.vforms.css',
+ 'resources/mediawiki.special/mediawiki.special.createAccount.vform.css',
+ ),
+ 'position' => 'top',
+ ),
+ 'mediawiki.special.createaccount.vform.js' => array(
+ 'scripts' => 'resources/mediawiki.special/mediawiki.special.createAccount.vform.js',
+ 'messages' => array(
+ 'createacct-captcha',
+ 'createacct-imgcaptcha-ph'
+ ),
+ 'dependencies' => 'mediawiki.jqueryMsg',
+ 'position' => 'top',
+ ),
'mediawiki.special.javaScriptTest' => array(
'scripts' => 'resources/mediawiki.special/mediawiki.special.javaScriptTest.js',
'messages' => array_merge( Skin::getSkinNameMessages(), array(
--- /dev/null
+/* Disable the underline that Vector puts on h2 headings, and bold them. */
+.mw-ui-container h2 {
+ border: 0;
+ font-weight: bold;
+}
+
+/* shuffled CAPTCHA */
+#wpCaptchaWord {
+ margin-top: 6px;
+}
+
+.mw-createacct-captcha-container {
+ background-color: #f8f8f8;
+ border: 1px solid #c9c9c9;
+ padding: 10px;
+ text-align: center;
+}
+
+.mw-createacct-captcha-image-container {
+ background-color: #fff;
+ min-height: 95px;
+}
+
+.mw-createacct-captcha-assisted {
+ display: block;
+ margin-top: 0.5em;
+}
+
+.mw-createacct-captcha-and-reload {
+ border: 1px solid #c9c9c9;
+ display: table-cell;
+ width: 270px;
+ background-color: #FFF;
+}
+
+.mw-createacct-captcha-and-reload .confirmedit-captcha-reload {
+ display: block;
+ float: right;
+}
+
+/* Benefits column CSS to the right (if it fits) of the form. */
+.mw-ui-container #userloginForm {
+ float: left;
+}
+
+div.mw-createacct-benefits-container {
+ float: left
+}
+
+div.mw-createacct-benefits-container h2 {
+ margin-bottom: 30px;
+}
+
+div.mw-benefits-icon {
+ display: inline-block;
+ padding: 0;
+ float: left;
+ width: 80px;
+ height: 75px;
+ margin-right: 15px;
+ border: 0;
+}
+
+.mw-benefits-icon.icon-edits {
+ /* @embed */
+ background: url(images/icon-edits.png) no-repeat right;
+}
+
+.mw-benefits-icon.icon-pages {
+ /* @embed */
+ background: url(images/icon-pages.png) no-repeat right;
+}
+
+.mw-benefits-icon.icon-contributors {
+ /* @embed */
+ background: url(images/icon-contributors.png) no-repeat right;
+}
+
+/* Special font for numbers in benefits*/
+div.mw-number-text h3 {
+ top: 0;
+ margin: 0;
+ padding: 0;
+ color: #252525;
+ font-family: 'Georgia', serif;
+ font-weight: normal;
+ font-size: 2.2em;
+ line-height: 1.2;
+ text-align: center;
+}
+
+div.mw-number-text {
+ display: block;
+ font-size: 1.2em;
+ color: #444;
+ margin-top: 1em;
+ text-align: center;
+}
--- /dev/null
+/**
+ * JavaScript for Create account form (Special:UserLogin?type=signup).
+ */
+( function ( mw, $ ) {
+
+ $( document ).ready( function( $ ) {
+ var $content = $( '#mw-content-text' ),
+ $submit = $content.find( '#wpCreateaccount' ),
+ tabIndex,
+ $captchaStuff,
+ helpMsg = mw.config.get( 'wgCreateacctImgcaptchaHelp' ),
+ captchaImage;
+
+ /*
+ * CAPTCHA
+ * The CAPTCHA is in a div style="captcha" at the top of the form.
+ * If it's a FancyCaptcha, then we remove it and insert it lower down,
+ * in a customized div with just what we need (e.g. no
+ * fancycaptcha-createaccount message).
+ */
+ if ( !$submit.length) {
+ return;
+ }
+ tabIndex = $submit.prop( 'tabindex' ) - 1;
+ $captchaStuff = $content.find ( '.captcha' );
+
+ if ( $captchaStuff.length ) {
+
+ // The FancyCaptcha image has this class in the ConfirmEdit extension
+ // after 2013-04-18.
+ captchaImage = $captchaStuff.find( 'img.fancycaptcha-image' );
+ if ( captchaImage.length !== 1 ) {
+ return;
+ }
+
+ $captchaStuff.remove();
+
+ // Insert another div before the submit button.
+ $submit.closest( 'div' )
+ .before( [
+ '<div>',
+ '<label for="wpCaptchaWord">' + mw.message( 'createacct-captcha' ).escaped() + '</label>',
+ '<div class="mw-createacct-captcha-container">',
+ '<div class="mw-createacct-captcha-and-reload">',
+ '<div class="mw-createacct-captcha-image-container">',
+ '<img id="mw-createacct-captcha" alt="PLACEHOLDER">',
+ '</div>',
+ '</div>',
+ '<input id="wpCaptchaWord" name="wpCaptchaWord" type="text" placeholder="' +
+ mw.message( 'createacct-imgcaptcha-ph' ).escaped() +
+ '" tabindex="' + tabIndex + '" autocapitalize="off" autocorrect="off">',
+ '<small class="mw-createacct-captcha-assisted">' + helpMsg + '</small>',
+ '</div>',
+ '</div>'
+ ].join( '' )
+ );
+
+ // Replace the placeholder img with the img from the old CAPTCHA.
+ captchaImage.replaceAll( $content.find( '#mw-createacct-captcha' ) );
+
+ // Append CAPTCHA reload, if any.
+ $( '.mw-createacct-captcha-and-reload' ).append( $captchaStuff.find( '.confirmedit-captcha-reload' ) );
+
+ // Find the input field, add the text (if any) of the existing CAPTCHA
+ // field (although usually it's blanked out on every redisplay),
+ // and after it move over the hidden field that tells the CAPTCHA
+ // what to do.
+ $content.find( '#wpCaptchaWord' )
+ .val( $captchaStuff.find( '#wpCaptchaWord' ).val() )
+ .after( $captchaStuff.find( '#wpCaptchaId' ) );
+ }
+
+ });
+
+}( mediaWiki, jQuery ) );
font-size: 0.8em;
}
+/* Put some space under template's header, which may contain CAPTCHA HTML.*/
+section.mw-form-header {
+ margin-bottom: 10px;
+}
+
/*
* Besides errorbox there could be warningbox, successbox, msgbox, though
* spage has never seen these in practice.
text-shadow: 0 1px #fae3e3;
word-wrap: break-word;
}
+
+/*
+ * Override the right margin of the form to give space in case a benefits
+ * column appears to the side.
+ *
+ */
+.mw-ui-container #userloginForm {
+ margin-right: 100px;
+}
padding: 0;
width: 100%;
}
-/* line 28, sourcefiles/scss/components/default/_forms.scss */
+/* line 27, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div input,
-.mw-ui-vform > div label,
.mw-ui-vform > div .mw-ui-button {
display: block;
-webkit-box-sizing: border-box;
margin: 0;
width: 100%;
}
-/* line 35, sourcefiles/scss/components/default/_forms.scss */
+/* line 34, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div input {
outline: 0;
border-style: solid;
box-shadow: #4091ed 0px 0px 5px;
border-color: #4091ed;
}
-/* line 39, sourcefiles/scss/components/default/_forms.scss */
+/* line 38, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div label {
+ display: block;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
font-size: 0.9em;
color: #7d7d7d;
width: auto;
padding: 0;
width: 100%;
}
-/* line 28, sourcefiles/scss/components/default/_forms.scss */
+/* line 27, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div input,
-.mw-ui-vform > div label,
.mw-ui-vform > div .mw-ui-button {
display: block;
-webkit-box-sizing: border-box;
margin: 0;
width: 100%;
}
-/* line 35, sourcefiles/scss/components/default/_forms.scss */
+/* line 34, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div input {
outline: 0;
border-style: solid;
box-shadow: #4091ed 0px 0px 5px;
border-color: #4091ed;
}
-/* line 39, sourcefiles/scss/components/default/_forms.scss */
+/* line 38, sourcefiles/scss/components/default/_forms.scss */
.mw-ui-vform > div label {
+ display: block;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
font-size: 0.9em;
color: #7d7d7d;
width: auto;
// MW currently doesn't use the type attribute everywhere on inputs.
input,
- label,
.mw-ui-button {
display: block;
@include box-sizing(border-box);
}
label {
+ display: block;
+ @include box-sizing(border-box);
@include agora-label-styling;
-
width: auto;
margin: 0 0 0.2em 0;
padding: 0;
</p>
!! end
+!! test
+Link containing an equals sign
+!! input
+[[Special:BookSources/isbn=4-00-026157-6]]
+!! result
+<p><a href="/wiki/Special:BookSources/isbn%3D4-00-026157-6" title="Special:BookSources/isbn=4-00-026157-6">Special:BookSources/isbn=4-00-026157-6</a>
+</p>
+!! end
+
+!! article
+Foo~bar
+!! text
+Just a test of an article title containing a tilde.
+!! endarticle
+
+# note that links containing signatures, like [[Foo~~~~]], are
+# massaged by the pre-save transform (PST) and so the tildes are never
+# seen by the parser.
+!! test
+Link containing a tilde
+!! input
+[[Foo~bar]]
+!! result
+<p><a href="/wiki/Foo%7Ebar" title="Foo~bar">Foo~bar</a>
+</p>
+!! end
+
!! test
Link containing double-single-quotes '' (bug 4598)
!! input
</p>
!! end
+!! article
+Söfnuður
+!! text
+Test.
+!! endarticle
+
+!! test
+Internal link with is linkprefix
+!! options
+language=is
+!! input
+Aðrir mótmælenda[[söfnuður|söfnuðir]] og
+!! result
+<p>Aðrir <a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðir</a> og
+</p>
+!! end
+
!! test
Parsoid-centric test: Whitespace in ext- and wiki-links should be preserved
!! input
* {{BASEPAGENAME}}
* {{SUBPAGENAME}}
* {{SUBPAGENAMEE}}
+* {{ROOTPAGENAME}}
+* {{ROOTPAGENAMEE}}
* {{BASEPAGENAME}}
* {{BASEPAGENAMEE}}
* {{TALKPAGENAME}}
</li><li> Parser_test
</li><li> Parser test
</li><li> Parser_test
+</li><li> Parser test
+</li><li> Parser_test
</li><li> Talk:Parser test
</li><li> Talk:Parser_test
</li><li> Parser test
"\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" );
}
+ // HACK: Call getLanguage() so the real $wgContLang is cached as the user language
+ // rather than our fake one. This is to avoid breaking other, unrelated tests.
+ RequestContext::getMain()->getLanguage();
+
$langCode = 'en'; # For mainpage to be 'Main Page'
$langObj = Language::factory( $langCode );
* debug function : dump the ipblocks table
*/
function dumpBlocks() {
- $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' );
+ $v = $this->db->select( 'ipblocks', '*' );
print "Got " . $v->numRows() . " rows. Full dump follow:\n";
foreach ( $v as $row ) {
print_r( $row );
global $wgLocalTZoffset;
$wgLocalTZoffset = -60;
$this->user->mBlockedby = $this->user->getName();
- $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 );
+ $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(),
+ 'no reason given', $now, 0, 10 );
$this->assertEquals( array( array( 'blockedtext',
'[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
* @ingroup Testing
*/
-class TestRecorder {
+/**
+ * Interface to record parser test results.
+ *
+ * The ITestRecorder is a very simple interface to record the result of
+ * MediaWiki parser tests. One should call start() before running the
+ * full parser tests and end() once all the tests have been finished.
+ * After each test, you should use record() to keep track of your tests
+ * results. Finally, report() is used to generate a summary of your
+ * test run, one could dump it to the console for human consumption or
+ * register the result in a database for tracking purposes.
+ *
+ * @since 1.22
+ */
+interface ITestRecorder {
+
+ /** Called at beginning of the parser test run */
+ public function start();
+
+ /** Called after each test */
+ public function record( $test, $result );
+
+ /** Called before finishing the test run */
+ public function report();
+
+ /** Called at the end of the parser test run */
+ public function end();
+
+}
+
+class TestRecorder implements ITestRecorder {
var $parent;
var $term;