Merge "Changing default copyright notice per WMF Legal's suggestion."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 23 Sep 2013 13:36:58 +0000 (13:36 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 23 Sep 2013 13:36:58 +0000 (13:36 +0000)
151 files changed:
.jshintignore
RELEASE-NOTES-1.22
docs/hooks.txt
includes/Action.php
includes/ChangeTags.php
includes/DefaultSettings.php
includes/Exception.php
includes/GitInfo.php
includes/GlobalFunctions.php
includes/MagicWord.php
includes/Sanitizer.php
includes/StringUtils.php
includes/Title.php
includes/WebRequest.php
includes/Wiki.php
includes/api/ApiFeedContributions.php
includes/clientpool/RedisConnectionPool.php
includes/db/DatabaseOracle.php
includes/db/DatabaseSqlite.php
includes/diff/DifferenceEngine.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.i18n.php
includes/job/jobs/RefreshLinksJob.php
includes/libs/CSSMin.php
includes/logging/LogPager.php
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php
includes/parser/Preprocessor_DOM.php
includes/resourceloader/ResourceLoader.php
includes/revisiondelete/RevisionDelete.php
includes/revisiondelete/RevisionDeleteAbstracts.php
includes/revisiondelete/RevisionDeleter.php
includes/search/SearchEngine.php
includes/site/SiteSQLStore.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialTags.php
includes/specials/SpecialUploadStash.php
languages/Language.php
languages/messages/MessagesAr.php
languages/messages/MessagesBcl.php
languages/messages/MessagesBg.php
languages/messages/MessagesBr.php
languages/messages/MessagesBs.php
languages/messages/MessagesCa.php
languages/messages/MessagesCe.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCs.php
languages/messages/MessagesDa.php
languages/messages/MessagesEn.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesFi.php
languages/messages/MessagesHe.php
languages/messages/MessagesHu.php
languages/messages/MessagesId.php
languages/messages/MessagesJa.php
languages/messages/MessagesLa.php
languages/messages/MessagesLb.php
languages/messages/MessagesLv.php
languages/messages/MessagesMs.php
languages/messages/MessagesNds_nl.php
languages/messages/MessagesNl.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesQqq.php
languages/messages/MessagesRu.php
languages/messages/MessagesSk.php
languages/messages/MessagesSr_ec.php
languages/messages/MessagesSr_el.php
languages/messages/MessagesTh.php
languages/messages/MessagesTl.php
languages/messages/MessagesTr.php
languages/messages/MessagesWuu.php
languages/messages/MessagesZh_hans.php
maintenance/mctest.php
maintenance/mssql/tables.sql
maintenance/oracle/tables.sql
maintenance/postgres/tables.sql
maintenance/tidyUpBug37714.php [new file with mode: 0644]
maintenance/update.php
resources/jquery.chosen/chosen-sprite@2x.png
resources/jquery.tipsy/images/tipsy.png
resources/jquery.ui/themes/default/images/ui-bg_flat_0_aaaaaa_40x100.png
resources/jquery.ui/themes/default/images/ui-bg_flat_75_ffffff_40x100.png
resources/jquery.ui/themes/default/images/ui-bg_glass_55_fbf9ee_1x400.png
resources/jquery.ui/themes/default/images/ui-bg_glass_65_ffffff_1x400.png
resources/jquery.ui/themes/default/images/ui-bg_glass_75_dadada_1x400.png
resources/jquery.ui/themes/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png
resources/jquery.ui/themes/vector/images/titlebar-fade.png
resources/jquery/images/jquery.arrowSteps.divider-ltr.png
resources/jquery/images/jquery.arrowSteps.divider-rtl.png
resources/jquery/images/jquery.arrowSteps.head-ltr.png
resources/jquery/images/jquery.arrowSteps.head-rtl.png
resources/jquery/images/jquery.arrowSteps.tail-ltr.png
resources/jquery/images/marker.png
resources/jquery/images/mask.png
resources/jquery/jquery.makeCollapsible.js
resources/jquery/jquery.suggestions.js
resources/mediawiki.api/mediawiki.api.category.js
resources/mediawiki.api/mediawiki.api.edit.js
resources/mediawiki.api/mediawiki.api.parse.js
resources/mediawiki.api/mediawiki.api.watch.js
resources/mediawiki.special/images/glyph-people-large.png
resources/mediawiki.special/images/icon-contributors.png
resources/mediawiki.special/images/icon-edits.png
resources/mediawiki.special/images/icon-lock.png
resources/mediawiki.special/images/icon-pages.png
resources/mediawiki/images/arrow-collapsed-ltr.png
resources/mediawiki/images/arrow-collapsed-rtl.png
resources/mediawiki/images/arrow-expanded.png
resources/mediawiki/mediawiki.user.js
skins/common/images/Arr_u.png
skins/common/images/ar/button_headline.png
skins/common/images/ar/button_nowiki.png
skins/common/images/arrow_disabled_left_25.png
skins/common/images/arrow_disabled_right_25.png
skins/common/images/arrow_right_25.png
skins/common/images/button_hr.png
skins/common/images/button_nowiki.png
skins/common/images/button_sig.png
skins/common/images/button_template.png
skins/common/images/critical-32.png
skins/common/images/fa/button_nowiki.png
skins/common/images/feed-icon.png
skins/common/images/magnify-clip-rtl.png
skins/common/images/question-small.png
skins/common/images/tick-32.png
skins/common/images/warning-32.png
skins/common/protect.js
skins/common/upload.js
skins/modern/external.png
skins/monobook/external-ltr.png
skins/monobook/external-rtl.png
skins/vector/images/edit-icon.png
skins/vector/images/external-link-ltr-icon.png
skins/vector/images/external-link-rtl-icon.png
skins/vector/images/mail-icon.png
skins/vector/images/news-icon.png
skins/vector/images/page-fade.png
skins/vector/images/portal-break-ltr.png
skins/vector/images/preferences-break.png
skins/vector/images/tab-break.png
skins/vector/images/talk-icon.png
skins/vector/images/video-icon.png
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/StringUtilsTest.php
tests/phpunit/includes/db/DatabaseTest.php
tests/phpunit/maintenance/DumpTestCase.php
thumb.php

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