Merge "Add a link to Special:WhatLinksHere in deleting-backlinks-warning"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 10 Mar 2014 18:50:26 +0000 (18:50 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 10 Mar 2014 18:50:26 +0000 (18:50 +0000)
263 files changed:
RELEASE-NOTES-1.23
includes/Message.php
includes/PathRouter.php
includes/PoolCounter.php
includes/SkinTemplate.php
includes/WebStart.php
includes/Wiki.php
includes/WikiPage.php
includes/api/ApiBlock.php
includes/api/ApiComparePages.php
includes/api/ApiDelete.php
includes/api/ApiDisabled.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedContributions.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFileRevert.php
includes/api/ApiHelp.php
includes/api/ApiImageRotate.php
includes/api/ApiLogin.php
includes/api/ApiLogout.php
includes/api/ApiMain.php
includes/api/ApiMove.php
includes/api/ApiOpenSearch.php
includes/api/ApiOptions.php
includes/api/ApiParamInfo.php
includes/api/ApiParse.php
includes/api/ApiPatrol.php
includes/api/ApiProtect.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllCategories.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllMessages.php
includes/api/ApiQueryAllPages.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryCategories.php
includes/api/ApiQueryCategoryInfo.php
includes/api/ApiQueryCategoryMembers.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryDuplicateFiles.php
includes/api/ApiQueryExtLinksUsage.php
includes/api/ApiQueryExternalLinks.php
includes/api/ApiQueryFilearchive.php
includes/api/ApiQueryIWBacklinks.php
includes/api/ApiQueryIWLinks.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryImages.php
includes/api/ApiQueryLangLinks.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryPagePropNames.php
includes/api/ApiQueryPageProps.php
includes/api/ApiQueryPagesWithProp.php
includes/api/ApiQueryProtectedTitles.php
includes/api/ApiQueryQueryPage.php
includes/api/ApiQueryRandom.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRedirects.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryStashImageInfo.php
includes/api/ApiQueryTags.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiQueryUsers.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiQueryWatchlistRaw.php
includes/api/ApiRevisionDelete.php
includes/api/ApiRollback.php
includes/api/ApiRsd.php
includes/api/ApiRunJobs.php
includes/api/ApiTokens.php
includes/api/ApiUnblock.php
includes/api/ApiUndelete.php
includes/api/ApiUpload.php
includes/api/ApiUserrights.php
includes/api/ApiWatch.php
includes/content/AbstractContent.php
includes/content/Content.php
includes/content/ContentHandler.php
includes/content/CssContent.php
includes/content/CssContentHandler.php
includes/content/JavaScriptContent.php
includes/content/JavaScriptContentHandler.php
includes/content/MessageContent.php
includes/content/TextContent.php
includes/content/TextContentHandler.php
includes/content/WikitextContent.php
includes/content/WikitextContentHandler.php
includes/diff/ArrayDiffFormatter.php
includes/diff/DairikiDiff.php
includes/diff/DiffFormatter.php
includes/diff/DifferenceEngine.php
includes/diff/TableDiffFormatter.php
includes/diff/UnifiedDiffFormatter.php
includes/diff/WikiDiff3.php
includes/htmlform/HTMLMultiSelectField.php
includes/htmlform/HTMLRadioField.php
includes/htmlform/HTMLSelectAndOtherField.php
includes/htmlform/HTMLSelectField.php
includes/htmlform/HTMLSelectOrOtherField.php
includes/installer/Installer.i18n.php
includes/installer/WebInstallerPage.php
includes/libs/CSSMin.php
includes/libs/lessc.inc.php
includes/objectcache/BagOStuff.php
includes/objectcache/MemcachedBagOStuff.php
includes/objectcache/MemcachedPeclBagOStuff.php
includes/objectcache/RedisBagOStuff.php
includes/resourceloader/ResourceLoader.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDeletedContributions.php
includes/specials/SpecialEmailuser.php
includes/templates/NoLocalSettings.php
languages/classes/LanguageUz.php
languages/messages/MessagesAr.php
languages/messages/MessagesBe.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBn.php
languages/messages/MessagesBo.php
languages/messages/MessagesCa.php
languages/messages/MessagesCe.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCs.php
languages/messages/MessagesCy.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesEgl.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.php
languages/messages/MessagesGu.php
languages/messages/MessagesHe.php
languages/messages/MessagesHr.php
languages/messages/MessagesHsb.php
languages/messages/MessagesHu.php
languages/messages/MessagesHy.php
languages/messages/MessagesIa.php
languages/messages/MessagesIlo.php
languages/messages/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKa.php
languages/messages/MessagesKk_cyrl.php
languages/messages/MessagesKo.php
languages/messages/MessagesKrc.php
languages/messages/MessagesKsh.php
languages/messages/MessagesLb.php
languages/messages/MessagesLez.php
languages/messages/MessagesLt.php
languages/messages/MessagesMk.php
languages/messages/MessagesMn.php
languages/messages/MessagesNap.php
languages/messages/MessagesNb.php
languages/messages/MessagesNl.php
languages/messages/MessagesNn.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesPt.php
languages/messages/MessagesPt_br.php
languages/messages/MessagesQqq.php
languages/messages/MessagesRo.php
languages/messages/MessagesRoa_tara.php
languages/messages/MessagesRu.php
languages/messages/MessagesRue.php
languages/messages/MessagesSa.php
languages/messages/MessagesSco.php
languages/messages/MessagesSl.php
languages/messages/MessagesSq.php
languages/messages/MessagesSr_ec.php
languages/messages/MessagesSr_el.php
languages/messages/MessagesSv.php
languages/messages/MessagesTa.php
languages/messages/MessagesTe.php
languages/messages/MessagesTh.php
languages/messages/MessagesTk.php
languages/messages/MessagesTl.php
languages/messages/MessagesTr.php
languages/messages/MessagesUk.php
languages/messages/MessagesUz.php
languages/messages/MessagesVi.php
languages/messages/MessagesYi.php
languages/messages/MessagesYue.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
maintenance/language/messages.inc
resources/jquery/jquery.client.js
resources/jquery/jquery.color.js
resources/jquery/jquery.hidpi.js
resources/jquery/jquery.localize.js
resources/mediawiki.api/mediawiki.api.category.js
resources/mediawiki.api/mediawiki.api.edit.js
resources/mediawiki.api/mediawiki.api.js
resources/mediawiki.api/mediawiki.api.parse.js
resources/mediawiki.api/mediawiki.api.watch.js
resources/mediawiki/mediawiki.js
resources/oojs-ui/i18n/ast.json
resources/oojs-ui/i18n/cu.json
resources/oojs-ui/i18n/fa.json
resources/oojs-ui/i18n/fi.json
resources/oojs-ui/i18n/he.json
resources/oojs-ui/i18n/hy.json
resources/oojs-ui/i18n/is.json
resources/oojs-ui/i18n/ko.json
resources/oojs-ui/i18n/lb.json
resources/oojs-ui/i18n/lt.json
resources/oojs-ui/i18n/nl.json
resources/oojs-ui/i18n/sq.json
resources/oojs-ui/i18n/sv.json
resources/oojs-ui/i18n/uk.json
resources/oojs-ui/i18n/vi.json
resources/oojs-ui/images/icons/add-item.png
resources/oojs-ui/images/icons/add-item.svg
resources/oojs-ui/oojs-ui-apex.css
resources/oojs-ui/oojs-ui.js
resources/oojs-ui/oojs-ui.svg.css
resources/oojs/oojs.js
resources/sinonjs/sinon-1.8.1.js [deleted file]
resources/sinonjs/sinon-1.9.0.js [new file with mode: 0644]
resources/sinonjs/sinon-ie-1.8.1.js [deleted file]
resources/sinonjs/sinon-ie-1.9.0.js [new file with mode: 0644]
skins/vector/components/search.less
tests/TestsAutoLoader.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/ResourceLoaderTestCase.php [new file with mode: 0644]
tests/phpunit/docs/ExportDemoTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/ResourceLoaderModuleTest.php [deleted file]
tests/phpunit/includes/ResourceLoaderTest.php [deleted file]
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/StatusTest.php
tests/phpunit/includes/WikiPageTest.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/exception/ErrorPageErrorTest.php [new file with mode: 0644]
tests/phpunit/includes/exception/ReadOnlyErrorTest.php [new file with mode: 0644]
tests/phpunit/includes/exception/UserNotLoggedInTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/RunningStatTest.php
tests/phpunit/includes/objectcache/BagOStuffTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php [new file with mode: 0644]
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php [new file with mode: 0644]
tests/phpunit/includes/upload/UploadFromUrlTest.php
tests/phpunit/includes/utils/UIDGeneratorTest.php
tests/phpunit/languages/SpecialPageAliasTest.php [new file with mode: 0644]
tests/phpunit/structure/StructureTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/jquery/jquery.color.test.js [new file with mode: 0644]
tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js [deleted file]
tests/qunit/suites/resources/jquery/jquery.makeCollapsible.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js

index bb807d9..bdb75e8 100644 (file)
@@ -41,6 +41,8 @@ production.
 * $wgSkipSkin, which has been replaceable by $wgSkipSkins since 2005 (r9249), is
   now formally deprecated.
 * Removed deprecated $wgDisabledActions as it is hardly used anywhere.
+* $wgRateLimitLog has been deprecated and replaced by
+  $wgDebugLogGroup['ratelimit'].
 
 === New features in 1.23 ===
 * ResourceLoader can utilize the Web Storage API to cache modules client-side.
@@ -114,6 +116,8 @@ production.
   whether to send a watchlist email notification.
 * (bug 42026) Special:Contributions now includes an option to filter page
   creations, similar to the topOnly option.
+* Add mediawiki.ui.button styling to all pages so wiki content can use styled
+  buttons.
 
 === Bug fixes in 1.23 ===
 * (bug 41759) The "updated since last visit" markers (on history pages, recent
index dd22844..7c9b095 100644 (file)
  * @since 1.17
  */
 class Message {
+
        /**
         * In which language to get this message. True, which is the default,
         * means the current interface language, false content language.
+        *
+        * @var bool
         */
        protected $interface = true;
 
@@ -172,12 +175,12 @@ class Message {
        protected $language = null;
 
        /**
-        * The message key.
+        * @var string|string[] The message key or array of keys.
         */
        protected $key;
 
        /**
-        * List of parameters which will be substituted into the message.
+        * @var array List of parameters which will be substituted into the message.
         */
        protected $parameters = array();
 
@@ -189,21 +192,23 @@ class Message {
         * * block-parse
         * * parse (default)
         * * plain
+        *
+        * @var string
         */
        protected $format = 'parse';
 
        /**
-        * Whether database can be used.
+        * @var bool Whether database can be used.
         */
        protected $useDatabase = true;
 
        /**
-        * Title object to use as context
+        * @var Title Title object to use as context.
         */
        protected $title = null;
 
        /**
-        * Content object representing the message
+        * @var Content Content object representing the message.
         */
        protected $content = null;
 
@@ -213,11 +218,11 @@ class Message {
        protected $message;
 
        /**
-        * Constructor.
         * @since 1.17
-        * @param $key: message key, or array of message keys to try and use the first non-empty message for
-        * @param array $params message parameters
-        * @return Message: $this
+        *
+        * @param string|string[] $key Message key or array of message keys to try and use the first
+        * non-empty message for.
+        * @param array $params Message parameters.
         */
        public function __construct( $key, $params = array() ) {
                global $wgLang;
@@ -227,7 +232,7 @@ class Message {
        }
 
        /**
-        * Returns the message key
+        * Returns the message key or the first from an array of message keys.
         *
         * @since 1.21
         *
@@ -244,18 +249,18 @@ class Message {
        }
 
        /**
-        * Returns the message parameters
+        * Returns the message parameters.
         *
         * @since 1.21
         *
-        * @return string[]
+        * @return array
         */
        public function getParams() {
                return $this->parameters;
        }
 
        /**
-        * Returns the message format
+        * Returns the message format.
         *
         * @since 1.21
         *
@@ -269,10 +274,13 @@ class Message {
         * Factory function that is just wrapper for the real constructor. It is
         * intended to be used instead of the real constructor, because it allows
         * chaining method calls, while new objects don't.
+        *
         * @since 1.17
-        * @param string $key message key
-        * @param Varargs: parameters as Strings
-        * @return Message: $this
+        *
+        * @param string|string[] $key Message key or array of keys.
+        * @param mixed [$param,...] Parameters as strings.
+        *
+        * @return Message
         */
        public static function newFromKey( $key /*...*/ ) {
                $params = func_get_args();
@@ -284,9 +292,13 @@ class Message {
         * Factory function accepting multiple message keys and returning a message instance
         * for the first message which is non-empty. If all messages are empty then an
         * instance of the first message key is returned.
+        *
         * @since 1.18
-        * @param Varargs: message keys (or first arg as an array of all the message keys)
-        * @return Message: $this
+        *
+        * @param string|string[] [$keys,...] Message keys, or first argument as an array of all the
+        * message keys.
+        *
+        * @return Message
         */
        public static function newFallbackSequence( /*...*/ ) {
                $keys = func_get_args();
@@ -304,9 +316,13 @@ class Message {
 
        /**
         * Adds parameters to the parameter list of this message.
+        *
         * @since 1.17
-        * @param Varargs: parameters as Strings, or a single argument that is an array of Strings
-        * @return Message: $this
+        *
+        * @param mixed [$params,...] Parameters as strings, or a single argument that is
+        * an array of strings.
+        *
+        * @return Message $this
         */
        public function params( /*...*/ ) {
                $args = func_get_args();
@@ -323,9 +339,13 @@ class Message {
         * In other words the parsing process cannot access the contents
         * of this type of parameter, and you need to make sure it is
         * sanitized beforehand.  The parser will see "$n", instead.
+        *
         * @since 1.17
-        * @param Varargs: raw parameters as Strings (or single argument that is an array of raw parameters)
-        * @return Message: $this
+        *
+        * @param mixed [$params,...] Raw parameters as strings, or a single argument that is
+        * an array of raw parameters.
+        *
+        * @return Message $this
         */
        public function rawParams( /*...*/ ) {
                $params = func_get_args();
@@ -341,9 +361,13 @@ class Message {
        /**
         * Add parameters that are numeric and will be passed through
         * Language::formatNum before substitution
+        *
         * @since 1.18
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param mixed [$param,...] Numeric parameters, or a single argument that is
+        * an array of numeric parameters.
+        *
+        * @return Message $this
         */
        public function numParams( /*...*/ ) {
                $params = func_get_args();
@@ -359,9 +383,13 @@ class Message {
        /**
         * Add parameters that are durations of time and will be passed through
         * Language::formatDuration before substitution
+        *
         * @since 1.22
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param int|int[] [$param,...] Duration parameters, or a single argument that is
+        * an array of duration parameters.
+        *
+        * @return Message $this
         */
        public function durationParams( /*...*/ ) {
                $params = func_get_args();
@@ -377,9 +405,13 @@ class Message {
        /**
         * Add parameters that are expiration times and will be passed through
         * Language::formatExpiry before substitution
+        *
         * @since 1.22
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param string|string[] [$param,...] Expiry parameters, or a single argument that is
+        * an array of expiry parameters.
+        *
+        * @return Message $this
         */
        public function expiryParams( /*...*/ ) {
                $params = func_get_args();
@@ -395,9 +427,13 @@ class Message {
        /**
         * Add parameters that are time periods and will be passed through
         * Language::formatTimePeriod before substitution
+        *
         * @since 1.22
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param number|number[] [$param,...] Time period parameters, or a single argument that is
+        * an array of time period parameters.
+        *
+        * @return Message $this
         */
        public function timeperiodParams( /*...*/ ) {
                $params = func_get_args();
@@ -413,9 +449,13 @@ class Message {
        /**
         * Add parameters that are file sizes and will be passed through
         * Language::formatSize before substitution
+        *
         * @since 1.22
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param int|int[] [$param,...] Size parameters, or a single argument that is
+        * an array of size parameters.
+        *
+        * @return Message $this
         */
        public function sizeParams( /*...*/ ) {
                $params = func_get_args();
@@ -431,9 +471,13 @@ class Message {
        /**
         * Add parameters that are bitrates and will be passed through
         * Language::formatBitrate before substitution
+        *
         * @since 1.22
-        * @param Varargs: numeric parameters (or single argument that is array of numeric parameters)
-        * @return Message: $this
+        *
+        * @param int|int[] [$param,...] Bit rate parameters, or a single argument that is
+        * an array of bit rate parameters.
+        *
+        * @return Message $this
         */
        public function bitrateParams( /*...*/ ) {
                $params = func_get_args();
@@ -448,9 +492,12 @@ class Message {
 
        /**
         * Set the language and the title from a context object
+        *
         * @since 1.19
+        *
         * @param $context IContextSource
-        * @return Message: $this
+        *
+        * @return Message $this
         */
        public function setContext( IContextSource $context ) {
                $this->inLanguage( $context->getLanguage() );
@@ -464,10 +511,13 @@ class Message {
         * Request the message in any language that is supported.
         * As a side effect interface message status is unconditionally
         * turned off.
+        *
         * @since 1.17
-        * @param $lang Mixed: language code or Language object.
+        *
+        * @param Language|string $lang Language code or Language object.
+        *
+        * @return Message $this
         * @throws MWException
-        * @return Message: $this
         */
        public function inLanguage( $lang ) {
                if ( $lang instanceof Language || $lang instanceof StubUserLang ) {
@@ -489,9 +539,11 @@ class Message {
        /**
         * Request the message in the wiki's content language,
         * unless it is disabled for this message.
+        *
         * @since 1.17
         * @see $wgForceUIMsgAsContentMsg
-        * @return Message: $this
+        *
+        * @return Message $this
         */
        public function inContentLanguage() {
                global $wgForceUIMsgAsContentMsg;
@@ -508,31 +560,40 @@ class Message {
        /**
         * Allows manipulating the interface message flag directly.
         * Can be used to restore the flag after setting a language.
-        * @param $value bool
-        * @return Message: $this
+        *
         * @since 1.20
+        *
+        * @param bool $interface
+        *
+        * @return Message $this
         */
-       public function setInterfaceMessageFlag( $value ) {
-               $this->interface = (bool)$value;
+       public function setInterfaceMessageFlag( $interface ) {
+               $this->interface = (bool)$interface;
                return $this;
        }
 
        /**
         * Enable or disable database use.
+        *
         * @since 1.17
-        * @param $value Boolean
-        * @return Message: $this
+        *
+        * @param bool $useDatabase
+        *
+        * @return Message $this
         */
-       public function useDatabase( $value ) {
-               $this->useDatabase = (bool)$value;
+       public function useDatabase( $useDatabase ) {
+               $this->useDatabase = (bool)$useDatabase;
                return $this;
        }
 
        /**
         * Set the Title object to use as context when transforming the message
+        *
         * @since 1.18
+        *
         * @param $title Title object
-        * @return Message: $this
+        *
+        * @return Message $this
         */
        public function title( $title ) {
                $this->title = $title;
@@ -541,6 +602,7 @@ class Message {
 
        /**
         * Returns the message as a Content object.
+        *
         * @return Content
         */
        public function content() {
@@ -553,8 +615,10 @@ class Message {
 
        /**
         * Returns the message parsed from wikitext to HTML.
+        *
         * @since 1.17
-        * @return String: HTML
+        *
+        * @return string HTML
         */
        public function toString() {
                $string = $this->fetchMessage();
@@ -605,8 +669,10 @@ class Message {
         * Magic method implementation of the above (for PHP >= 5.2.0), so we can do, eg:
         *     $foo = Message::get( $key );
         *     $string = "<abbr>$foo</abbr>";
+        *
         * @since 1.18
-        * @return String
+        *
+        * @return string
         */
        public function __toString() {
                // PHP doesn't allow __toString to throw exceptions and will
@@ -630,9 +696,11 @@ class Message {
        }
 
        /**
-        * Fully parse the text from wikitext to HTML
+        * Fully parse the text from wikitext to HTML.
+        *
         * @since 1.17
-        * @return String parsed HTML
+        *
+        * @return string Parsed HTML.
         */
        public function parse() {
                $this->format = 'parse';
@@ -641,8 +709,10 @@ class Message {
 
        /**
         * Returns the message text. {{-transformation is done.
+        *
         * @since 1.17
-        * @return String: Unescaped message text.
+        *
+        * @return string Unescaped message text.
         */
        public function text() {
                $this->format = 'text';
@@ -651,8 +721,10 @@ class Message {
 
        /**
         * Returns the message text as-is, only parameters are substituted.
+        *
         * @since 1.17
-        * @return String: Unescaped untransformed message text.
+        *
+        * @return string Unescaped untransformed message text.
         */
        public function plain() {
                $this->format = 'plain';
@@ -661,8 +733,10 @@ class Message {
 
        /**
         * Returns the parsed message text which is always surrounded by a block element.
+        *
         * @since 1.17
-        * @return String: HTML
+        *
+        * @return string HTML
         */
        public function parseAsBlock() {
                $this->format = 'block-parse';
@@ -672,8 +746,10 @@ class Message {
        /**
         * Returns the message text. {{-transformation is done and the result
         * is escaped excluding any raw parameters.
+        *
         * @since 1.17
-        * @return String: Escaped message text.
+        *
+        * @return string Escaped message text.
         */
        public function escaped() {
                $this->format = 'escaped';
@@ -682,8 +758,10 @@ class Message {
 
        /**
         * Check whether a message key has been defined currently.
+        *
         * @since 1.17
-        * @return Bool: true if it is and false if not.
+        *
+        * @return bool
         */
        public function exists() {
                return $this->fetchMessage() !== false;
@@ -691,9 +769,11 @@ class Message {
 
        /**
         * Check whether a message does not exist, or is an empty string
+        *
         * @since 1.18
-        * @return Bool: true if is is and false if not
         * @todo FIXME: Merge with isDisabled()?
+        *
+        * @return bool
         */
        public function isBlank() {
                $message = $this->fetchMessage();
@@ -701,9 +781,11 @@ class Message {
        }
 
        /**
-        * Check whether a message does not exist, is an empty string, or is "-"
+        * Check whether a message does not exist, is an empty string, or is "-".
+        *
         * @since 1.18
-        * @return Bool: true if it is and false if not
+        *
+        * @return bool
         */
        public function isDisabled() {
                $message = $this->fetchMessage();
@@ -712,72 +794,89 @@ class Message {
 
        /**
         * @since 1.17
-        * @param $value
-        * @return array
+        *
+        * @param mixed $raw
+        *
+        * @return array Array with a single "raw" key.
         */
-       public static function rawParam( $value ) {
-               return array( 'raw' => $value );
+       public static function rawParam( $raw ) {
+               return array( 'raw' => $raw );
        }
 
        /**
         * @since 1.18
-        * @param $value
-        * @return array
+        *
+        * @param mixed $num
+        *
+        * @return array Array with a single "num" key.
         */
-       public static function numParam( $value ) {
-               return array( 'num' => $value );
+       public static function numParam( $num ) {
+               return array( 'num' => $num );
        }
 
        /**
         * @since 1.22
-        * @param $value
-        * @return array
+        *
+        * @param int $duration
+        *
+        * @return int[] Array with a single "duration" key.
         */
-       public static function durationParam( $value ) {
-               return array( 'duration' => $value );
+       public static function durationParam( $duration ) {
+               return array( 'duration' => $duration );
        }
 
        /**
         * @since 1.22
-        * @param $value
-        * @return array
+        *
+        * @param string $expiry
+        *
+        * @return string[] Array with a single "expiry" key.
         */
-       public static function expiryParam( $value ) {
-               return array( 'expiry' => $value );
+       public static function expiryParam( $expiry ) {
+               return array( 'expiry' => $expiry );
        }
 
        /**
         * @since 1.22
-        * @param $value
-        * @return array
+        *
+        * @param number $period
+        *
+        * @return number[] Array with a single "period" key.
         */
-       public static function timeperiodParam( $value ) {
-               return array( 'period' => $value );
+       public static function timeperiodParam( $period ) {
+               return array( 'period' => $period );
        }
 
        /**
         * @since 1.22
-        * @param $value
-        * @return array
+        *
+        * @param int $size
+        *
+        * @return int[] Array with a single "size" key.
         */
-       public static function sizeParam( $value ) {
-               return array( 'size' => $value );
+       public static function sizeParam( $size ) {
+               return array( 'size' => $size );
        }
 
        /**
         * @since 1.22
-        * @param $value
-        * @return array
+        *
+        * @param int $bitrate
+        *
+        * @return int[] Array with a single "bitrate" key.
         */
-       public static function bitrateParam( $value ) {
-               return array( 'bitrate' => $value );
+       public static function bitrateParam( $bitrate ) {
+               return array( 'bitrate' => $bitrate );
        }
 
        /**
         * Substitutes any parameters into the message text.
+        *
         * @since 1.17
-        * @param string $message the message text
-        * @param string $type either before or after
+        *
+        * @param string $message The message text.
+        * @param string $type Either "before" or "after".
+        *
         * @return String
         */
        protected function replaceParameters( $message, $type = 'before' ) {
@@ -794,9 +893,12 @@ class Message {
 
        /**
         * Extracts the parameter type and preprocessed the value if needed.
+        *
         * @since 1.18
-        * @param string|array $param Parameter as defined in this class.
-        * @return Tuple(type, value)
+        *
+        * @param mixed $param Parameter as defined in this class.
+        *
+        * @return array Array with the parameter type (either "before" or "after") and the value.
         */
        protected function extractParam( $param ) {
                if ( is_array( $param ) ) {
@@ -837,9 +939,12 @@ class Message {
 
        /**
         * Wrapper for what ever method we use to parse wikitext.
+        *
         * @since 1.17
-        * @param string $string Wikitext message contents
-        * @return string Wikitext parsed into HTML
+        *
+        * @param string $string Wikitext message contents.
+        *
+        * @return string Wikitext parsed into HTML.
         */
        protected function parseText( $string ) {
                $out = MessageCache::singleton()->parse( $string, $this->title, /*linestart*/true, $this->interface, $this->language );
@@ -848,8 +953,11 @@ class Message {
 
        /**
         * Wrapper for what ever method we use to {{-transform wikitext.
+        *
         * @since 1.17
-        * @param string $string Wikitext message contents
+        *
+        * @param string $string Wikitext message contents.
+        *
         * @return string Wikitext with {{-constructs replaced with their values.
         */
        protected function transformText( $string ) {
@@ -857,10 +965,12 @@ class Message {
        }
 
        /**
-        * Wrapper for what ever method we use to get message contents
+        * Wrapper for what ever method we use to get message contents.
+        *
         * @since 1.17
-        * @throws MWException
+        *
         * @return string
+        * @throws MWException If message key array is empty.
         */
        protected function fetchMessage() {
                if ( !isset( $this->message ) ) {
@@ -899,13 +1009,15 @@ class Message {
  * @since 1.21
  */
 class RawMessage extends Message {
+
        /**
         * Call the parent constructor, then store the key as
         * the message.
         *
-        * @param string $key Message to use
-        * @param array $params Parameters for the message
         * @see Message::__construct
+        *
+        * @param string|string[] $key Message to use.
+        * @param array $params Parameters for the message.
         */
        public function __construct( $key, $params = array() ) {
                parent::__construct( $key, $params );
@@ -925,4 +1037,5 @@ class RawMessage extends Message {
                }
                return $this->message;
        }
+
 }
index 435e09e..d367e4d 100644 (file)
@@ -27,7 +27,7 @@
  *
  * $router->add( "/wiki/$1" );
  *   - Matches /wiki/Foo style urls and extracts the title
- * $router->add( array( 'edit' => "/edit/$1" ), array( 'action' => '$key' ) );
+ * $router->add( array( 'edit' => "/edit/$key" ), array( 'action' => '$key' ) );
  *   - Matches /edit/Foo style urls and sets action=edit
  * $router->add( '/$2/$1',
  *   array( 'variant' => '$2' ),
index 3d4c464..85c4c79 100644 (file)
@@ -91,6 +91,13 @@ abstract class PoolCounter {
                return new $class( $conf, $type, $key );
        }
 
+       /**
+        * @return string
+        */
+       public function getKey() {
+               return $this->key;
+       }
+
        /**
         * I want to do this task and I need to do it myself.
         *
@@ -175,7 +182,7 @@ abstract class PoolCounterWork {
         * Do something with the error, like showing it to the user.
         * @return bool
         */
-       function error( $status ) {
+       public function error( $status ) {
                return false;
        }
 
@@ -185,8 +192,10 @@ abstract class PoolCounterWork {
         * @param $status Status
         * @return void
         */
-       function logError( $status ) {
-               wfDebugLog( 'poolcounter', "Pool key '{$this->key}': "
+       public function logError( $status ) {
+               $key = $this->poolCounter->getKey();
+
+               wfDebugLog( 'poolcounter', "Pool key '$key': "
                        . $status->getMessage()->inLanguage( 'en' )->useDatabase( false )->text() );
        }
 
@@ -314,14 +323,14 @@ class PoolCounterWorkViaCallback extends PoolCounterWork {
                return false;
        }
 
-       function fallback() {
+       public function fallback() {
                if ( $this->fallback ) {
                        return call_user_func_array( $this->fallback, array() );
                }
                return false;
        }
 
-       function error( $status ) {
+       public function error( $status ) {
                if ( $this->error ) {
                        return call_user_func_array( $this->error, array( $status ) );
                }
index 8bccaec..780b228 100644 (file)
@@ -104,7 +104,11 @@ class SkinTemplate extends Skin {
         * @param $out OutputPage
         */
        function setupSkinUserCss( OutputPage $out ) {
-               $out->addModuleStyles( array( 'mediawiki.legacy.shared', 'mediawiki.legacy.commonPrint' ) );
+               $out->addModuleStyles( array(
+                       'mediawiki.legacy.shared',
+                       'mediawiki.legacy.commonPrint',
+                       'mediawiki.ui.button'
+               ) );
        }
 
        /**
index 58c953a..eb79134 100644 (file)
@@ -126,8 +126,8 @@ if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
 
        # LocalSettings.php is the per site customization file. If it does not exist
        # the wiki installer needs to be launched or the generated file uploaded to
-       # the root wiki directory
-       if ( !file_exists( MW_CONFIG_FILE ) ) {
+       # the root wiki directory. Give a hint, if it is not readable by the server.
+       if ( !is_readable( MW_CONFIG_FILE ) ) {
                require_once "$IP/includes/templates/NoLocalSettings.php";
                die();
        }
index 5c67e5f..d78d7cb 100644 (file)
@@ -644,7 +644,8 @@ class MediaWiki {
                $query['signature'] = ApiRunJobs::getQuerySignature( $query );
 
                if ( !$wgEnableAPI ) {
-                       ApiRunJobs::executeJobs( $n ); // slow fallback
+                       // Fall back to running the job here while the user waits
+                       ApiRunJobs::executeJobs( $n );
                        return;
                }
 
@@ -660,7 +661,8 @@ class MediaWiki {
                wfRestoreWarnings();
                if ( !$sock ) {
                        wfDebugLog( 'runJobs', "Failed to start cron API (socket error $errno): $errstr\n" );
-                       ApiRunJobs::executeJobs( $n ); // slow fallback
+                       // Fall back to running the job here while the user waits
+                       ApiRunJobs::executeJobs( $n );
                        return;
                }
 
index 3de0475..b4aa303 100644 (file)
@@ -1568,7 +1568,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @param $flags Int
         * @return Int updated $flags
         */
-       function checkFlags( $flags ) {
+       public function checkFlags( $flags ) {
                if ( !( $flags & EDIT_NEW ) && !( $flags & EDIT_UPDATE ) ) {
                        if ( $this->exists() ) {
                                $flags |= EDIT_UPDATE;
@@ -2945,6 +2945,29 @@ class WikiPage implements Page, IDBAccessObject {
                        return array( array( 'notvisiblerev' ) );
                }
 
+               // Set patrolling and bot flag on the edits, which gets rollbacked.
+               // This is done before the rollback edit to have patrolling also on failure (bug 62157).
+               $set = array();
+               if ( $bot && $guser->isAllowed( 'markbotedits' ) ) {
+                       // Mark all reverted edits as bot
+                       $set['rc_bot'] = 1;
+               }
+
+               if ( $wgUseRCPatrol ) {
+                       // Mark all reverted edits as patrolled
+                       $set['rc_patrolled'] = 1;
+               }
+
+               if ( count( $set ) ) {
+                       $dbw->update( 'recentchanges', $set,
+                               array( /* WHERE */
+                                       'rc_cur_id' => $current->getPage(),
+                                       'rc_user_text' => $current->getUserText(),
+                                       'rc_timestamp > ' . $dbw->addQuotes( $s->rev_timestamp ),
+                               ), __METHOD__
+                       );
+               }
+
                // Generate the edit summary if necessary
                $target = Revision::newFromId( $s->rev_id );
                if ( empty( $summary ) ) {
@@ -3001,27 +3024,6 @@ class WikiPage implements Page, IDBAccessObject {
                        ) );
                }
 
-               $set = array();
-               if ( $bot && $guser->isAllowed( 'markbotedits' ) ) {
-                       // Mark all reverted edits as bot
-                       $set['rc_bot'] = 1;
-               }
-
-               if ( $wgUseRCPatrol ) {
-                       // Mark all reverted edits as patrolled
-                       $set['rc_patrolled'] = 1;
-               }
-
-               if ( count( $set ) ) {
-                       $dbw->update( 'recentchanges', $set,
-                               array( /* WHERE */
-                                       'rc_cur_id' => $current->getPage(),
-                                       'rc_user_text' => $current->getUserText(),
-                                       'rc_timestamp > ' . $dbw->addQuotes( $s->rev_timestamp ),
-                               ), __METHOD__
-                       );
-               }
-
                $revId = $status->value['revision']->getId();
 
                wfRunHooks( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
@@ -3508,7 +3510,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param $parserOptions parserOptions to use for the parse operation
         * @param $content Content|String: content to parse or null to load it; may also be given as a wikitext string, for BC
         */
-       function __construct( Page $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null ) {
+       public function __construct( Page $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null ) {
                if ( is_string( $content ) ) { // BC: old style call
                        $modelId = $page->getRevision()->getContentModel();
                        $format = $page->getRevision()->getContentFormat();
@@ -3554,7 +3556,7 @@ class PoolWorkArticleView extends PoolCounterWork {
        /**
         * @return bool
         */
-       function doWork() {
+       public function doWork() {
                global $wgUseFileCache;
 
                // @todo several of the methods called on $this->page are not declared in Page, but present
@@ -3617,7 +3619,7 @@ class PoolWorkArticleView extends PoolCounterWork {
        /**
         * @return bool
         */
-       function getCachedWork() {
+       public function getCachedWork() {
                $this->parserOutput = ParserCache::singleton()->get( $this->page, $this->parserOptions );
 
                if ( $this->parserOutput === false ) {
@@ -3632,7 +3634,7 @@ class PoolWorkArticleView extends PoolCounterWork {
        /**
         * @return bool
         */
-       function fallback() {
+       public function fallback() {
                $this->parserOutput = ParserCache::singleton()->getDirty( $this->page, $this->parserOptions );
 
                if ( $this->parserOutput === false ) {
@@ -3651,7 +3653,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param $status Status
         * @return bool
         */
-       function error( $status ) {
+       public function error( $status ) {
                $this->error = $status;
                return false;
        }
index 332fa9e..364300e 100644 (file)
@@ -222,7 +222,7 @@ class ApiBlock extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Block a user';
+               return 'Block a user.';
        }
 
        public function getPossibleErrors() {
index 237e8c8..c1bbea7 100644 (file)
@@ -157,8 +157,8 @@ class ApiComparePages extends ApiBase {
 
        public function getDescription() {
                return array(
-                       'Get the difference between 2 pages',
-                       'You must pass a revision number or a page title or a page ID id for each part (1 and 2)'
+                       'Get the difference between 2 pages.',
+                       'You must pass a revision number or a page title or a page ID id for each part (1 and 2).'
                );
        }
 
index c09cad3..acc2eb8 100644 (file)
@@ -240,7 +240,7 @@ class ApiDelete extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Delete a page';
+               return 'Delete a page.';
        }
 
        public function getPossibleErrors() {
index e5ef3b7..6ea5d20 100644 (file)
@@ -53,7 +53,7 @@ class ApiDisabled extends ApiBase {
        }
 
        public function getDescription() {
-               return 'This module has been disabled';
+               return 'This module has been disabled.';
        }
 
        public function getExamples() {
index d5c789c..28ed5e4 100644 (file)
@@ -108,7 +108,7 @@ class ApiExpandTemplates extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Expands all templates in wikitext';
+               return 'Expands all templates in wikitext.';
        }
 
        public function getPossibleErrors() {
index 2cdc875..4173402 100644 (file)
@@ -208,7 +208,7 @@ class ApiFeedContributions extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Returns a user contributions feed';
+               return 'Returns a user contributions feed.';
        }
 
        public function getPossibleErrors() {
index 84c1fae..4770365 100644 (file)
@@ -266,7 +266,7 @@ class ApiFeedWatchlist extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Returns a watchlist feed';
+               return 'Returns a watchlist feed.';
        }
 
        public function getPossibleErrors() {
index a3fa5f9..1941fbd 100644 (file)
@@ -167,7 +167,7 @@ class ApiFileRevert extends ApiBase {
 
        public function getDescription() {
                return array(
-                       'Revert a file to an old version'
+                       'Revert a file to an old version.'
                );
        }
 
index 5b1f29c..e584d0d 100644 (file)
@@ -152,7 +152,7 @@ class ApiHelp extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Display this help screen. Or the help screen for the specified module';
+               return 'Display this help screen. Or the help screen for the specified module.';
        }
 
        public function getExamples() {
index 5d2ee6f..b8e16ab 100644 (file)
@@ -203,7 +203,7 @@ class ApiImageRotate extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Rotate one or more images';
+               return 'Rotate one or more images.';
        }
 
        public function needsToken() {
index fe3143e..cba2134 100644 (file)
@@ -261,7 +261,7 @@ class ApiLogin extends ApiBase {
                        'In the event of a successful log-in, a cookie will be attached to your session.',
                        'In the event of a failed log-in, you will not be able to attempt another log-in',
                        'through this method for 5 seconds. This is to prevent password guessing by',
-                       'automated password crackers'
+                       'automated password crackers.'
                );
        }
 
index 2ba92a6..c8b3882 100644 (file)
@@ -59,7 +59,7 @@ class ApiLogout extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Log out and clear session data';
+               return 'Log out and clear session data.';
        }
 
        public function getExamples() {
index 0939dea..1a11b52 100644 (file)
@@ -1111,14 +1111,14 @@ class ApiMain extends ApiBase {
                        '',
                        'Status:                All features shown on this page should be working, but the API',
                        '                       is still in active development, and may change at any time.',
-                       '                       Make sure to monitor our mailing list for any updates',
+                       '                       Make sure to monitor our mailing list for any updates.',
                        '',
                        'Erroneous requests:    When erroneous requests are sent to the API, a HTTP header will be sent',
                        '                       with the key "MediaWiki-API-Error" and then both the value of the',
-                       '                       header and the error code sent back will be set to the same value',
+                       '                       header and the error code sent back will be set to the same value.',
                        '',
                        '                       In the case of an invalid action being passed, these will have a value',
-                       '                       of "unknown_action"',
+                       '                       of "unknown_action".',
                        '',
                        '                       For more information see https://www.mediawiki.org' .
                                '/wiki/API:Errors_and_warnings',
@@ -1162,12 +1162,11 @@ class ApiMain extends ApiBase {
        protected function getCredits() {
                return array(
                        'API developers:',
-                       '    Roan Kattouw - roan . kattouw @ gmail . com (lead developer Sep 2007-2009)',
-                       '    Victor Vasiliev - vasilvv @ gmail . com',
-                       '    Bryan Tong Minh - bryan . tongminh @ gmail . com',
-                       '    Sam Reed - sam @ reedyboy . net',
-                       '    Yuri Astrakhan - yuri . astrakhan @ gmail . com (creator, lead ' .
-                               'developer Sep 2006-Sep 2007, 2012-present)',
+                       '    Roan Kattouw (lead developer Sep 2007-2009)',
+                       '    Victor Vasiliev',
+                       '    Bryan Tong Minh',
+                       '    Sam Reed',
+                       '    Yuri Astrakhan (creator, lead developer Sep 2006-Sep 2007, 2012-present)',
                        '',
                        'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
                        'or file a bug report at https://bugzilla.wikimedia.org/'
index 20ac48a..10b655f 100644 (file)
@@ -272,7 +272,7 @@ class ApiMove extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Move a page';
+               return 'Move a page.';
        }
 
        public function getPossibleErrors() {
index 4b8578b..f2bf754 100644 (file)
@@ -125,7 +125,7 @@ class ApiOpenSearch extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Search the wiki using the OpenSearch protocol';
+               return 'Search the wiki using the OpenSearch protocol.';
        }
 
        public function getExamples() {
index fb441a3..86d051a 100644 (file)
@@ -174,10 +174,11 @@ class ApiOptions extends ApiBase {
                        'token' => 'An options token previously obtained through the action=tokens',
                        'reset' => 'Resets preferences to the site defaults',
                        'resetkinds' => 'List of types of options to reset when the "reset" option is set',
-                       'change' => 'List of changes, formatted name=value (e.g. skin=vector), ' .
-                               'value cannot contain pipe characters. If no value is given (not ' .
+                       'change' => array( 'List of changes, formatted name=value (e.g. skin=vector), ' .
+                               'value cannot contain pipe characters. If no value is given (not ',
                                'even an equals sign), e.g., optionname|otheroption|..., the ' .
-                               'option will be reset to its default value',
+                               'option will be reset to its default value'
+                       ),
                        'optionname' => 'A name of a option which should have an optionvalue set',
                        'optionvalue' => 'A value of the option specified by the optionname, ' .
                                'can contain pipe characters',
@@ -186,7 +187,7 @@ class ApiOptions extends ApiBase {
 
        public function getDescription() {
                return array(
-                       'Change preferences of the current user',
+                       'Change preferences of the current user.',
                        'Only options which are registered in core or in one of installed extensions,',
                        'or as options with keys prefixed with \'userjs-\' (intended to be used by user',
                        'scripts), can be set.'
index 2b4710a..5092af0 100644 (file)
@@ -349,7 +349,7 @@ class ApiParamInfo extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Obtain information about certain API parameters and errors';
+               return 'Obtain information about certain API parameters and errors.';
        }
 
        public function getExamples() {
index 47ad80f..ce52565 100644 (file)
@@ -818,9 +818,9 @@ class ApiParse extends ApiBase {
                $p = $this->getModulePrefix();
 
                return array(
-                       'Parses content and returns parser output',
+                       'Parses content and returns parser output.',
                        'See the various prop-Modules of action=query to get information from the current' .
-                               'version of a page',
+                               'version of a page.',
                        'There are several ways to specify the text to parse:',
                        "1) Specify a page or revision, using {$p}page, {$p}pageid, or {$p}oldid.",
                        "2) Specify content explicitly, using {$p}text, {$p}title, and {$p}contentmodel.",
index 46bd94e..00297ec 100644 (file)
@@ -109,7 +109,7 @@ class ApiPatrol extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Patrol a page or revision';
+               return 'Patrol a page or revision.';
        }
 
        public function getPossibleErrors() {
index 644e97e..27f0f1e 100644 (file)
@@ -212,7 +212,7 @@ class ApiProtect extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Change the protection level of a page';
+               return 'Change the protection level of a page.';
        }
 
        public function getPossibleErrors() {
index 49ab591..c6ae611 100644 (file)
@@ -736,7 +736,7 @@ class ApiQuery extends ApiBase {
                                'from the MediaWiki databases,',
                        'and is loosely based on the old query.php interface.',
                        'All data modifications will first have to use query to acquire a ' .
-                               'token to prevent abuse from malicious sites'
+                               'token to prevent abuse from malicious sites.'
                );
        }
 
index 44bf0cb..8a1810b 100644 (file)
@@ -225,7 +225,7 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Enumerate all categories';
+               return 'Enumerate all categories.';
        }
 
        public function getExamples() {
index 4095bd8..0591fa9 100644 (file)
@@ -394,7 +394,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Enumerate all images sequentially';
+               return 'Enumerate all images sequentially.';
        }
 
        public function getPossibleErrors() {
index 6b1d5a2..09f40fd 100644 (file)
@@ -285,7 +285,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Return messages from this site';
+               return 'Return messages from this site.';
        }
 
        public function getExamples() {
index 501154a..8ae8f3e 100644 (file)
@@ -341,7 +341,7 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Enumerate all pages sequentially in a given namespace';
+               return 'Enumerate all pages sequentially in a given namespace.';
        }
 
        public function getPossibleErrors() {
index 748dbaf..7915118 100644 (file)
@@ -438,7 +438,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Enumerate all registered users';
+               return 'Enumerate all registered users.';
        }
 
        public function getPossibleErrors() {
index bda1e03..9502d11 100644 (file)
@@ -534,13 +534,13 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
        public function getDescription() {
                switch ( $this->getModuleName() ) {
                        case 'backlinks':
-                               return 'Find all pages that link to the given page';
+                               return 'Find all pages that link to the given page.';
                        case 'embeddedin':
-                               return 'Find all pages that embed (transclude) the given title';
+                               return 'Find all pages that embed (transclude) the given title.';
                        case 'imageusage':
                                return 'Find all pages that use the given image title.';
                        default:
-                               ApiBase::dieDebug( __METHOD__, 'Unknown module name' );
+                               ApiBase::dieDebug( __METHOD__, 'Unknown module name.' );
                }
        }
 
index 47768cb..6cc0183 100644 (file)
@@ -408,7 +408,7 @@ class ApiQueryBlocks extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'List all blocked users and IP addresses';
+               return 'List all blocked users and IP addresses.';
        }
 
        public function getPossibleErrors() {
index c5b12b3..30d7449 100644 (file)
@@ -254,7 +254,7 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'List all categories the page(s) belong to';
+               return 'List all categories the page(s) belong to.';
        }
 
        public function getPossibleErrors() {
index 574ef6e..d0e3a36 100644 (file)
@@ -143,7 +143,7 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Returns information about the given categories';
+               return 'Returns information about the given categories.';
        }
 
        public function getExamples() {
index f7bd59a..4e942d6 100644 (file)
@@ -401,7 +401,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'List all pages in a given category';
+               return 'List all pages in a given category.';
        }
 
        public function getPossibleErrors() {
index 37fb489..912ac02 100644 (file)
@@ -275,7 +275,7 @@ class ApiQueryContributors extends ApiQueryBase {
 
        public function getDescription() {
                return 'Get the list of logged-in contributors and ' .
-                       'the count of anonymous contributors to a page';
+                       'the count of anonymous contributors to a page.';
        }
 
        public function getExamples() {
index 365fe3f..f738c50 100644 (file)
@@ -492,12 +492,12 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                return array(
                        'List deleted revisions.',
                        'Operates in three modes:',
-                       ' 1) List deleted revisions for the given title(s), sorted by timestamp',
-                       ' 2) List deleted contributions for the given user, sorted by timestamp (no titles specified)',
+                       ' 1) List deleted revisions for the given title(s), sorted by timestamp.',
+                       ' 2) List deleted contributions for the given user, sorted by timestamp (no titles specified).',
                        " 3) List all deleted revisions in the given namespace, sorted by title and timestamp',
-                       '    (no titles specified, {$p}user not set)",
+                       '    (no titles specified, {$p}user not set).",
                        'Certain parameters only apply to some modes and are ignored in others.',
-                       'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3',
+                       'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.',
                );
        }
 
index 1854694..3105f91 100644 (file)
@@ -200,7 +200,7 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'List all files that are duplicates of the given file(s) based on hash values';
+               return 'List all files that are duplicates of the given file(s) based on hash values.';
        }
 
        public function getExamples() {
index d220817..f09fbd5 100644 (file)
@@ -257,7 +257,7 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Enumerate pages that contain a given URL';
+               return 'Enumerate pages that contain a given URL.';
        }
 
        public function getPossibleErrors() {
index 5803ea7..f7a0958 100644 (file)
@@ -150,7 +150,7 @@ class ApiQueryExternalLinks extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Returns all external URLs (not interwikis) from the given page(s)';
+               return 'Returns all external URLs (not interwikis) from the given page(s).';
        }
 
        public function getPossibleErrors() {
index bcbc642..e12d927 100644 (file)
@@ -367,7 +367,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Enumerate all deleted files sequentially';
+               return 'Enumerate all deleted files sequentially.';
        }
 
        public function getPossibleErrors() {
index 03a72a6..e4cecd5 100644 (file)
@@ -231,7 +231,7 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
                return array( 'Find all pages that link to the given interwiki link.',
                        'Can be used to find all links with a prefix, or',
                        'all links to a title (with a given prefix).',
-                       'Using neither parameter is effectively "All IW Links"',
+                       'Using neither parameter is effectively "All IW Links".',
                );
        }
 
index be64d36..a7b69a0 100644 (file)
@@ -185,7 +185,7 @@ class ApiQueryIWLinks extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Returns all interwiki links from the given page(s)';
+               return 'Returns all interwiki links from the given page(s).';
        }
 
        public function getPossibleErrors() {
index 95c1420..369d4c9 100644 (file)
@@ -873,7 +873,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Returns image information and upload history';
+               return 'Returns image information and upload history.';
        }
 
        public function getPossibleErrors() {
index a32fb9e..a66ad40 100644 (file)
@@ -180,7 +180,7 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Returns all images contained on the given page(s)';
+               return 'Returns all images contained on the given page(s).';
        }
 
        public function getExamples() {
index 5a45a28..8e155f2 100644 (file)
@@ -213,7 +213,7 @@ class ApiQueryLangLinks extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Returns all interlanguage links from the given page(s)';
+               return 'Returns all interlanguage links from the given page(s).';
        }
 
        public function getPossibleErrors() {
index 1eecbe2..dd816cf 100644 (file)
@@ -233,7 +233,7 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return "Returns all {$this->description}s from the given page(s)";
+               return "Returns all {$this->description}s from the given page(s).";
        }
 
        public function getExamples() {
index 848c6ce..b607ca5 100644 (file)
@@ -103,7 +103,26 @@ class ApiQueryLogEvents extends ApiQueryBase {
                }
 
                if ( !is_null( $params['action'] ) ) {
-                       list( $type, $action ) = explode( '/', $params['action'] );
+                       // Do validation of action param, list of allowed actions can contains wildcards
+                       // Allow the param, when the actions is in the list or a wildcard version is listed.
+                       $logAction = $params['action'];
+                       if ( strpos( $logAction, '/' ) === false ) {
+                               // all items in the list have a slash
+                               $valid = false;
+                       } else {
+                               $logActions = array_flip( $this->getAllowedLogActions() );
+                               list( $type, $action ) = explode( '/', $logAction, 2 );
+                               $valid = isset( $logActions[$logAction] ) || isset( $logActions[$type . '/*'] );
+                       }
+
+                       if ( !$valid ) {
+                               $valueName = $this->encodeParamName( 'action' );
+                               $this->dieUsage(
+                                       "Unrecognized value for parameter '$valueName': {$logAction}",
+                                       "unknown_$valueName"
+                               );
+                       }
+
                        $this->addWhereFld( 'log_type', $type );
                        $this->addWhereFld( 'log_action', $action );
                } elseif ( !is_null( $params['type'] ) ) {
@@ -404,6 +423,12 @@ class ApiQueryLogEvents extends ApiQueryBase {
                return $vals;
        }
 
+       private function getAllowedLogActions() {
+               global $wgLogActions, $wgLogActionsHandlers;
+
+               return array_keys( array_merge( $wgLogActions, $wgLogActionsHandlers ) );
+       }
+
        public function getCacheMode( $params ) {
                if ( $this->userCanSeeRevDel() ) {
                        return 'private';
@@ -420,8 +445,8 @@ class ApiQueryLogEvents extends ApiQueryBase {
                }
        }
 
-       public function getAllowedParams() {
-               global $wgLogTypes, $wgLogActions, $wgLogActionsHandlers;
+       public function getAllowedParams( $flags = 0 ) {
+               global $wgLogTypes;
 
                return array(
                        'prop' => array(
@@ -444,7 +469,10 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                ApiBase::PARAM_TYPE => $wgLogTypes
                        ),
                        'action' => array(
-                               ApiBase::PARAM_TYPE => array_keys( array_merge( $wgLogActions, $wgLogActionsHandlers ) )
+                               // validation on request is done in execute()
+                               ApiBase::PARAM_TYPE => ( $flags & ApiBase::GET_VALUES_FOR_HELP )
+                                       ? $this->getAllowedLogActions()
+                                       : null
                        ),
                        'start' => array(
                                ApiBase::PARAM_TYPE => 'timestamp'
@@ -491,7 +519,10 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                ' tags           - Lists tags for the event',
                        ),
                        'type' => 'Filter log entries to only this type',
-                       'action' => "Filter log actions to only this type. Overrides {$p}type",
+                       'action' => array(
+                               "Filter log actions to only this action. Overrides {$p}type",
+                               "Wildcard actions like 'action/*' allows to specify any string for the asterisk"
+                       ),
                        'start' => 'The timestamp to start enumerating from',
                        'end' => 'The timestamp to end enumerating',
                        'dir' => $this->getDirectionDescription( $p ),
@@ -561,7 +592,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Get events from logs';
+               return 'Get events from logs.';
        }
 
        public function getPossibleErrors() {
index 5438175..c387475 100644 (file)
@@ -102,7 +102,7 @@ class ApiQueryPagePropNames extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'List all page prop names in use on the wiki';
+               return 'List all page prop names in use on the wiki.';
        }
 
        public function getExamples() {
index e51c7ab..52be5ca 100644 (file)
@@ -141,7 +141,7 @@ class ApiQueryPageProps extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Get various properties defined in the page content';
+               return 'Get various properties defined in the page content.';
        }
 
        public function getExamples() {
index e68eb56..df07249 100644 (file)
@@ -174,7 +174,7 @@ class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'List all pages using a given page prop';
+               return 'List all pages using a given page prop.';
        }
 
        public function getExamples() {
index ea350ad..9cdd6b9 100644 (file)
@@ -258,7 +258,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'List all titles protected from creation';
+               return 'List all titles protected from creation.';
        }
 
        public function getExamples() {
index 88af62b..2fc2676 100644 (file)
@@ -203,7 +203,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Get a list provided by a QueryPage-based special page';
+               return 'Get a list provided by a QueryPage-based special page.';
        }
 
        public function getPossibleErrors() {
index 0d54ffe..5f85e0e 100644 (file)
@@ -185,13 +185,13 @@ class ApiQueryRandom extends ApiQueryGeneratorBase {
 
        public function getDescription() {
                return array(
-                       'Get a set of random pages',
+                       'Get a set of random pages.',
                        'NOTE: Pages are listed in a fixed sequence, only the starting point is random.',
                        '      This means that if, for example, "Main Page" is the first random page on',
                        '      your list, "List of fictional monkeys" will *always* be second, "List of',
-                       '      people on stamps of Vanuatu" third, etc',
+                       '      people on stamps of Vanuatu" third, etc.',
                        'NOTE: If the number of pages in the namespace is lower than rnlimit, you will',
-                       '      get fewer pages. You will not get the same page twice'
+                       '      get fewer pages. You will not get the same page twice.'
                );
        }
 
index 6ccc288..0284916 100644 (file)
@@ -281,8 +281,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        /* Add fields to our query if they are specified as a needed parameter. */
                        $this->addFieldsIf( array( 'rc_this_oldid', 'rc_last_oldid' ), $this->fld_ids );
                        $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
-                       $this->addFieldsIf( 'rc_user', $this->fld_user );
-                       $this->addFieldsIf( 'rc_user_text', $this->fld_user || $this->fld_userid );
+                       $this->addFieldsIf( 'rc_user', $this->fld_user || $this->fld_userid );
+                       $this->addFieldsIf( 'rc_user_text', $this->fld_user );
                        $this->addFieldsIf( array( 'rc_minor', 'rc_type', 'rc_bot' ), $this->fld_flags );
                        $this->addFieldsIf( array( 'rc_old_len', 'rc_new_len' ), $this->fld_sizes );
                        $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
@@ -892,7 +892,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Enumerate recent changes';
+               return 'Enumerate recent changes.';
        }
 
        public function getPossibleErrors() {
index c046109..1deb1f8 100644 (file)
@@ -249,7 +249,7 @@ class ApiQueryRedirects extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Returns all redirects to the given page(s)';
+               return 'Returns all redirects to the given page(s).';
        }
 
        public function getExamples() {
index 65cb16d..033976f 100644 (file)
@@ -874,12 +874,12 @@ class ApiQueryRevisions extends ApiQueryBase {
 
        public function getDescription() {
                return array(
-                       'Get revision information',
+                       'Get revision information.',
                        'May be used in several ways:',
-                       ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter',
-                       ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params',
-                       ' 3) Get data about a set of revisions by setting their IDs with revids parameter',
-                       'All parameters marked as (enum) may only be used with a single page (#2)'
+                       ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
+                       ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.',
+                       ' 3) Get data about a set of revisions by setting their IDs with revids parameter.',
+                       'All parameters marked as (enum) may only be used with a single page (#2).'
                );
        }
 
index 1132a60..fcaaf10 100644 (file)
@@ -416,7 +416,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return 'Perform a full text search';
+               return 'Perform a full text search.';
        }
 
        public function getPossibleErrors() {
index a078013..1cd8d98 100644 (file)
@@ -821,7 +821,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Return general information about the site';
+               return 'Return general information about the site.';
        }
 
        public function getPossibleErrors() {
index 248b3d8..3595cf9 100644 (file)
@@ -129,7 +129,7 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
        }
 
        public function getDescription() {
-               return 'Returns image information for stashed images';
+               return 'Returns image information for stashed images.';
        }
 
        public function getExamples() {
index 33116ce..9e2559f 100644 (file)
@@ -188,7 +188,7 @@ class ApiQueryTags extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'List change tags';
+               return 'List change tags.';
        }
 
        public function getExamples() {
index 16108a2..b58a951 100644 (file)
@@ -601,7 +601,7 @@ class ApiQueryContributions extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Get all edits by a user';
+               return 'Get all edits by a user.';
        }
 
        public function getPossibleErrors() {
index 37cf483..200b03b 100644 (file)
@@ -299,7 +299,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Get information about the current user';
+               return 'Get information about the current user.';
        }
 
        public function getExamples() {
index cd4a8fc..d98cc39 100644 (file)
@@ -387,7 +387,7 @@ class ApiQueryUsers extends ApiQueryBase {
        }
 
        public function getDescription() {
-               return 'Get information about a list of users';
+               return 'Get information about a list of users.';
        }
 
        public function getExamples() {
index b7dc865..6baa87d 100644 (file)
@@ -674,7 +674,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return "Get all recent changes to pages in the logged in user's watchlist";
+               return "Get all recent changes to pages in the logged in user's watchlist.";
        }
 
        public function getPossibleErrors() {
index b53bea1..f45d0e4 100644 (file)
@@ -205,7 +205,7 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
        }
 
        public function getDescription() {
-               return "Get all pages on the logged in user's watchlist";
+               return "Get all pages on the logged in user's watchlist.";
        }
 
        public function getPossibleErrors() {
index 05457b3..1400b0d 100644 (file)
@@ -217,7 +217,7 @@ class ApiRevisionDelete extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Delete/undelete revisions';
+               return 'Delete/undelete revisions.';
        }
 
        public function getPossibleErrors() {
index 2a372e4..70a2fec 100644 (file)
@@ -141,7 +141,7 @@ class ApiRollback extends ApiBase {
        public function getDescription() {
                return array(
                        'Undo the last edit to the page. If the last user who edited the page made',
-                       'multiple edits in a row, they will all be rolled back'
+                       'multiple edits in a row, they will all be rolled back.'
                );
        }
 
index e01f0fa..285177c 100644 (file)
@@ -60,7 +60,7 @@ class ApiRsd extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Export an RSD (Really Simple Discovery) schema';
+               return 'Export an RSD (Really Simple Discovery) schema.';
        }
 
        public function getExamples() {
index e16dc5d..05327c8 100644 (file)
@@ -94,10 +94,14 @@ class ApiRunJobs extends ApiBase {
                        return;
                }
                try {
-                       // Fallback to running the jobs here while the user waits
                        $group = JobQueueGroup::singleton();
+                       $count = $group->executeReadyPeriodicTasks();
+                       if ( $count > 0 ) {
+                               wfDebugLog( 'jobqueue', "Executed $count periodic queue task(s)." );
+                       }
+
                        do {
-                               $job = $group->pop( JobQueueGroup::USE_CACHE ); // job from any queue
+                               $job = $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE ); // job from any queue
                                if ( $job ) {
                                        $output = $job->toString() . "\n";
                                        $t = - microtime( true );
@@ -157,7 +161,7 @@ class ApiRunJobs extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Perform periodic tasks or run jobs from the queue';
+               return 'Perform periodic tasks or run jobs from the queue.';
        }
 
        public function getExamples() {
index 6862668..5e197db 100644 (file)
@@ -98,7 +98,7 @@ class ApiTokens extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Gets tokens for data-modifying actions';
+               return 'Gets tokens for data-modifying actions.';
        }
 
        protected function getExamples() {
index 46e2f6e..f34d4df 100644 (file)
@@ -131,7 +131,7 @@ class ApiUnblock extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Unblock a user';
+               return 'Unblock a user.';
        }
 
        public function getPossibleErrors() {
index 93cefef..332ed51 100644 (file)
@@ -143,7 +143,7 @@ class ApiUndelete extends ApiBase {
        public function getDescription() {
                return array(
                        'Restore certain revisions of a deleted page. A list of deleted revisions ',
-                       '(including timestamps) can be retrieved through list=deletedrevs'
+                       '(including timestamps) can be retrieved through list=deletedrevs.'
                );
        }
 
index 7d0d78e..c54e8ba 100644 (file)
@@ -819,7 +819,7 @@ class ApiUpload extends ApiBase {
                        ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
                        ' * Complete an earlier upload that failed due to warnings, using the "filekey" parameter',
                        'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
-                       'sending the "file". Also you must get and send an edit token before doing any upload stuff'
+                       'sending the "file". Also you must get and send an edit token before doing any upload stuff.'
                );
        }
 
index 2bd7321..0bed859 100644 (file)
@@ -123,7 +123,7 @@ class ApiUserrights extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Add/remove a user to/from groups';
+               return 'Add/remove a user to/from groups.';
        }
 
        public function needsToken() {
index 100ee96..6dfb1b4 100644 (file)
@@ -211,7 +211,7 @@ class ApiWatch extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Add or remove pages from/to the current user\'s watchlist';
+               return 'Add or remove pages from/to the current user\'s watchlist.';
        }
 
        public function getPossibleErrors() {
index e1b1f01..f2f0c9d 100644 (file)
@@ -43,7 +43,7 @@ abstract class AbstractContent implements Content {
        protected $model_id;
 
        /**
-        * @param string|null $modelId
+        * @param string $modelId
         *
         * @since 1.21
         */
@@ -52,23 +52,21 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::getModel
-        *
         * @since 1.21
+        *
+        * @see Content::getModel
         */
        public function getModel() {
                return $this->model_id;
        }
 
        /**
-        * Throws an MWException if $model_id is not the id of the content model
-        * supported by this Content object.
-        *
         * @since 1.21
         *
         * @param string $modelId The model to check
         *
-        * @throws MWException
+        * @throws MWException If the provided ID is not the ID of the content model supported by this
+        * Content object.
         */
        protected function checkModelID( $modelId ) {
                if ( $modelId !== $this->model_id ) {
@@ -81,40 +79,40 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::getContentHandler
-        *
         * @since 1.21
+        *
+        * @see Content::getContentHandler
         */
        public function getContentHandler() {
                return ContentHandler::getForContent( $this );
        }
 
        /**
-        * @see Content::getDefaultFormat
-        *
         * @since 1.21
+        *
+        * @see Content::getDefaultFormat
         */
        public function getDefaultFormat() {
                return $this->getContentHandler()->getDefaultFormat();
        }
 
        /**
-        * @see Content::getSupportedFormats
-        *
         * @since 1.21
+        *
+        * @see Content::getSupportedFormats
         */
        public function getSupportedFormats() {
                return $this->getContentHandler()->getSupportedFormats();
        }
 
        /**
-        * @see Content::isSupportedFormat
+        * @since 1.21
         *
         * @param string $format
         *
-        * @since 1.21
+        * @return bool
         *
-        * @return boolean
+        * @see Content::isSupportedFormat
         */
        public function isSupportedFormat( $format ) {
                if ( !$format ) {
@@ -125,13 +123,11 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * Throws an MWException if $this->isSupportedFormat( $format ) does not
-        * return true.
-        *
         * @since 1.21
         *
-        * @param string $format
-        * @throws MWException
+        * @param string $format The serialization format to check.
+        *
+        * @throws MWException If the format is not supported by this content handler.
         */
        protected function checkFormat( $format ) {
                if ( !$this->isSupportedFormat( $format ) ) {
@@ -143,48 +139,50 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::serialize
-        *
-        * @param string|null $format
-        *
         * @since 1.21
         *
+        * @param string $format
+        *
         * @return string
+        *
+        * @see Content::serialize
         */
        public function serialize( $format = null ) {
                return $this->getContentHandler()->serializeContent( $this, $format );
        }
 
        /**
-        * @see Content::isEmpty
-        *
         * @since 1.21
         *
-        * @return boolean
+        * @return bool
+        *
+        * @see Content::isEmpty
         */
        public function isEmpty() {
                return $this->getSize() === 0;
        }
 
        /**
-        * @see Content::isValid
+        * Subclasses may override this to implement (light weight) validation.
         *
         * @since 1.21
         *
-        * @return boolean
+        * @return bool Always true.
+        *
+        * @see Content::isValid
         */
        public function isValid() {
                return true;
        }
 
        /**
-        * @see Content::equals
-        *
         * @since 1.21
         *
-        * @param Content|null $that
+        * @param Content $that
         *
-        * @return boolean
+        * @return bool
+        *
+        * @see Content::equals
         */
        public function equals( Content $that = null ) {
                if ( is_null( $that ) ) {
@@ -214,26 +212,19 @@ abstract class AbstractContent implements Content {
         * Subclasses may override this to determine the secondary data updates more
         * efficiently, preferably without the need to generate a parser output object.
         *
-        * @see Content::getSecondaryDataUpdates()
+        * @since 1.21
         *
-        * @param $title Title The context for determining the necessary updates
-        * @param $old Content|null An optional Content object representing the
-        *    previous content, i.e. the content being replaced by this Content
-        *    object.
-        * @param $recursive boolean Whether to include recursive updates (default:
-        *    false).
-        * @param $parserOutput ParserOutput|null Optional ParserOutput object.
-        *    Provide if you have one handy, to avoid re-parsing of the content.
+        * @param Title $title
+        * @param Content $old
+        * @param bool $recursive
+        * @param ParserOutput $parserOutput
         *
-        * @return Array. A list of DataUpdate objects for putting information
-        *    about this content object somewhere.
+        * @return DataUpdate[]
         *
-        * @since 1.21
+        * @see Content::getSecondaryDataUpdates()
         */
-       public function getSecondaryDataUpdates( Title $title,
-               Content $old = null,
-               $recursive = true, ParserOutput $parserOutput = null
-       ) {
+       public function getSecondaryDataUpdates( Title $title, Content $old = null,
+               $recursive = true, ParserOutput $parserOutput = null ) {
                if ( $parserOutput === null ) {
                        $parserOutput = $this->getParserOutput( $title, null, null, false );
                }
@@ -242,9 +233,11 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::getRedirectChain
-        *
         * @since 1.21
+        *
+        * @return Title[]|null
+        *
+        * @see Content::getRedirectChain
         */
        public function getRedirectChain() {
                global $wgMaxRedirects;
@@ -277,19 +270,26 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::getRedirectTarget
+        * Subclasses that implement redirects should override this.
         *
         * @since 1.21
+        *
+        * @return null
+        *
+        * @see Content::getRedirectTarget
         */
        public function getRedirectTarget() {
                return null;
        }
 
        /**
-        * @see Content::getUltimateRedirectTarget
-        * @note: migrated here from Title::newFromRedirectRecurse
+        * @note Migrated here from Title::newFromRedirectRecurse.
         *
         * @since 1.21
+        *
+        * @return Title|null
+        *
+        * @see Content::getUltimateRedirectTarget
         */
        public function getUltimateRedirectTarget() {
                $titles = $this->getRedirectChain();
@@ -298,80 +298,93 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::isRedirect
-        *
         * @since 1.21
         *
         * @return bool
+        *
+        * @see Content::isRedirect
         */
        public function isRedirect() {
                return $this->getRedirectTarget() !== null;
        }
 
        /**
-        * @see Content::updateRedirect
-        *
         * This default implementation always returns $this.
-        *
-        * @param Title $target
+        * Subclasses that implement redirects should override this.
         *
         * @since 1.21
         *
+        * @param Title $target
+        *
         * @return Content $this
+        *
+        * @see Content::updateRedirect
         */
        public function updateRedirect( Title $target ) {
                return $this;
        }
 
        /**
-        * @see Content::getSection
-        *
         * @since 1.21
+        *
+        * @return null
+        *
+        * @see Content::getSection
         */
        public function getSection( $sectionId ) {
                return null;
        }
 
        /**
-        * @see Content::replaceSection
-        *
         * @since 1.21
+        *
+        * @return null
+        *
+        * @see Content::replaceSection
         */
        public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
                return null;
        }
 
        /**
-        * @see Content::preSaveTransform
-        *
         * @since 1.21
+        *
+        * @return Content $this
+        *
+        * @see Content::preSaveTransform
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
                return $this;
        }
 
        /**
-        * @see Content::addSectionHeader
-        *
         * @since 1.21
+        *
+        * @return Content $this
+        *
+        * @see Content::addSectionHeader
         */
        public function addSectionHeader( $header ) {
                return $this;
        }
 
        /**
-        * @see Content::preloadTransform
-        *
         * @since 1.21
+        *
+        * @return Content $this
+        *
+        * @see Content::preloadTransform
         */
        public function preloadTransform( Title $title, ParserOptions $popts ) {
                return $this;
        }
 
        /**
-        * @see Content::prepareSave
-        *
         * @since 1.21
+        *
+        * @return Status
+        *
+        * @see Content::prepareSave
         */
        public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user ) {
                if ( $this->isValid() ) {
@@ -382,21 +395,16 @@ abstract class AbstractContent implements Content {
        }
 
        /**
-        * @see Content::getDeletionUpdates
-        *
         * @since 1.21
         *
-        * @param $page WikiPage the deleted page
-        * @param $parserOutput null|ParserOutput optional parser output object
-        *    for efficient access to meta-information about the content object.
-        *    Provide if you have one handy.
+        * @param WikiPage $page
+        * @param ParserOutput $parserOutput
         *
-        * @return array A list of DataUpdate instances that will clean up the
-        *    database after deletion.
+        * @return LinksDeletionUpdate[]
+        *
+        * @see Content::getDeletionUpdates
         */
-       public function getDeletionUpdates( WikiPage $page,
-               ParserOutput $parserOutput = null
-       ) {
+       public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
                return array(
                        new LinksDeletionUpdate( $page ),
                );
@@ -406,30 +414,28 @@ abstract class AbstractContent implements Content {
         * This default implementation always returns false. Subclasses may override
         * this to supply matching logic.
         *
-        * @see Content::matchMagicWord
-        *
         * @since 1.21
         *
         * @param MagicWord $word
         *
-        * @return bool
+        * @return bool Always false.
+        *
+        * @see Content::matchMagicWord
         */
        public function matchMagicWord( MagicWord $word ) {
                return false;
        }
 
        /**
-        * @see Content::convert()
-        *
         * This base implementation calls the hook ConvertContent to enable custom conversions.
         * Subclasses may override this to implement conversion for "their" content model.
         *
-        * @param string $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
-        * @param string $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
-        * not allowed, full round-trip conversion is expected to work without losing information.
+        * @param string $toModel
+        * @param string $lossy
+        *
+        * @return Content|bool
         *
-        * @return Content|bool A content object with the content model $toModel, or false if
-        * that conversion is not supported.
+        * @see Content::convert()
         */
        public function convert( $toModel, $lossy = '' ) {
                if ( $this->getModel() === $toModel ) {
index 947e348..075635d 100644 (file)
@@ -32,6 +32,7 @@
  * @ingroup Content
  */
 interface Content {
+
        /**
         * @since 1.21
         *
@@ -64,8 +65,9 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param int $maxLength Maximum length of the summary text
-        * @return string The summary text
+        * @param int $maxLength Maximum length of the summary text.
+        *
+        * @return string The summary text.
         */
        public function getTextForSummary( $maxLength = 250 );
 
@@ -132,7 +134,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return Array of supported serialization formats
+        * @return string[] List of supported serialization formats
         */
        public function getSupportedFormats();
 
@@ -147,7 +149,8 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param string $format The format to check
+        * @param string $format The serialization format to check.
+        *
         * @return bool Whether the format is supported
         */
        public function isSupportedFormat( $format );
@@ -159,9 +162,9 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $format null|string The desired serialization format (or null for
-        *    the default format).
-        * @return string Serialized form of this Content object
+        * @param string $format The desired serialization format, or null for the default format.
+        *
+        * @return string Serialized form of this Content object.
         */
        public function serialize( $format = null );
 
@@ -184,7 +187,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return boolean
+        * @return bool
         */
        public function isValid();
 
@@ -207,7 +210,8 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $that Content The Content object to compare to
+        * @param Content $that The Content object to compare to.
+        *
         * @return bool True if this Content object is equal to $that, false otherwise.
         */
        public function equals( Content $that = null );
@@ -242,7 +246,8 @@ interface Content {
         * @param bool $hasLinks If it is known whether this content contains
         *    links, provide this information here, to avoid redundant parsing to
         *    find out.
-        * @return boolean
+        *
+        * @return bool
         */
        public function isCountable( $hasLinks = null );
 
@@ -256,10 +261,10 @@ interface Content {
         *       generated parser output, implementations of this method
         *       may call ParserOutput::recordOption() on the output object.
         *
-        * @param $title Title The page title to use as a context for rendering
-        * @param $revId null|int The revision being rendered (optional)
-        * @param $options null|ParserOptions Any parser options
-        * @param $generateHtml Boolean Whether to generate HTML (default: true). If false,
+        * @param Title $title The page title to use as a context for rendering.
+        * @param int $revId Optional revision ID being rendered.
+        * @param ParserOptions $options Any parser options.
+        * @param bool $generateHtml Whether to generate HTML (default: true). If false,
         *        the result of calling getText() on the ParserOutput object returned by
         *        this method is undefined.
         *
@@ -267,8 +272,7 @@ interface Content {
         *
         * @return ParserOutput
         */
-       public function getParserOutput( Title $title,
-               $revId = null,
+       public function getParserOutput( Title $title, $revId = null,
                ParserOptions $options = null, $generateHtml = true );
 
        // TODO: make RenderOutput and RenderOptions base classes
@@ -288,24 +292,22 @@ interface Content {
         * Subclasses may implement this to determine the necessary updates more
         * efficiently, or make use of information about the old content.
         *
-        * @param $title Title The context for determining the necessary updates
-        * @param $old Content|null An optional Content object representing the
+        * @param Title $title The context for determining the necessary updates
+        * @param Content $old An optional Content object representing the
         *    previous content, i.e. the content being replaced by this Content
         *    object.
-        * @param $recursive boolean Whether to include recursive updates (default:
+        * @param bool $recursive Whether to include recursive updates (default:
         *    false).
-        * @param $parserOutput ParserOutput|null Optional ParserOutput object.
+        * @param ParserOutput $parserOutput Optional ParserOutput object.
         *    Provide if you have one handy, to avoid re-parsing of the content.
         *
-        * @return Array. A list of DataUpdate objects for putting information
+        * @return DataUpdate[] A list of DataUpdate objects for putting information
         *    about this content object somewhere.
         *
         * @since 1.21
         */
-       public function getSecondaryDataUpdates( Title $title,
-               Content $old = null,
-               $recursive = true, ParserOutput $parserOutput = null
-       );
+       public function getSecondaryDataUpdates( Title $title, Content $old = null,
+               $recursive = true, ParserOutput $parserOutput = null );
 
        /**
         * Construct the redirect destination from this content and return an
@@ -315,7 +317,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return Array of Titles, with the destination last
+        * @return Title[]|null List of Titles, with the destination last.
         */
        public function getRedirectChain();
 
@@ -327,7 +329,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return Title: The corresponding Title
+        * @return Title|null The corresponding Title.
         */
        public function getRedirectTarget();
 
@@ -344,7 +346,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @return Title
+        * @return Title|null
         */
        public function getUltimateRedirectTarget();
 
@@ -364,9 +366,9 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param Title $target the new redirect target
+        * @param Title $target The new redirect target
         *
-        * @return Content a new Content object with the updated redirect (or $this
+        * @return Content A new Content object with the updated redirect (or $this
         *   if this Content object isn't a redirect)
         */
        public function updateRedirect( Title $target );
@@ -380,7 +382,8 @@ interface Content {
         *    The ID "0" retrieves the section before the first heading, "1" the
         *    text between the first heading (included) and the second heading
         *    (excluded), etc.
-        * @return Content|Boolean|null The section, or false if no such section
+        *
+        * @return Content|bool|null The section, or false if no such section
         *    exist, or null if sections are not supported.
         */
        public function getSection( $sectionId );
@@ -391,10 +394,11 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $section null/false or a section number (0, 1, 2, T1, T2...), or "new"
-        * @param $with Content: new content of the section
-        * @param string $sectionTitle new section's subject, only if $section is 'new'
-        * @return string Complete article text, or null if error
+        * @param mixed $section Null/false or a section number (0, 1, 2, T1, T2...), or "new"
+        * @param Content $with New content of the section
+        * @param string $sectionTitle New section's subject, only if $section is 'new'
+        *
+        * @return string|null Complete article text, or null if error
         */
        public function replaceSection( $section, Content $with, $sectionTitle = '' );
 
@@ -404,9 +408,10 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $title Title
-        * @param $user User
-        * @param $parserOptions null|ParserOptions
+        * @param Title $title
+        * @param User $user
+        * @param ParserOptions $parserOptions
+        *
         * @return Content
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $parserOptions );
@@ -418,7 +423,8 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $header string
+        * @param string $header
+        *
         * @return Content
         */
        public function addSectionHeader( $header );
@@ -429,8 +435,9 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $title Title
-        * @param $parserOptions null|ParserOptions
+        * @param Title $title
+        * @param ParserOptions $parserOptions
+        *
         * @return Content
         */
        public function preloadTransform( Title $title, ParserOptions $parserOptions );
@@ -451,15 +458,15 @@ interface Content {
         * @since 1.21
         *
         * @param WikiPage $page The page to be saved.
-        * @param int $flags bitfield for use with EDIT_XXX constants, see WikiPage::doEditContent()
-        * @param int $baseRevId the ID of the current revision
+        * @param int $flags Bitfield for use with EDIT_XXX constants, see WikiPage::doEditContent()
+        * @param int $baseRevId The ID of the current revision
         * @param User $user
         *
         * @return Status A status object indicating whether the content was
         *   successfully prepared for saving. If the returned status indicates
         *   an error, a rollback will be performed and the transaction aborted.
         *
-        * @see see WikiPage::doEditContent()
+        * @see WikiPage::doEditContent()
         */
        public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user );
 
@@ -470,12 +477,12 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param $page WikiPage the deleted page
-        * @param $parserOutput null|ParserOutput optional parser output object
+        * @param WikiPage $page The deleted page
+        * @param ParserOutput $parserOutput Optional parser output object
         *    for efficient access to meta-information about the content object.
         *    Provide if you have one handy.
         *
-        * @return array A list of DataUpdate instances that will clean up the
+        * @return DataUpdate[] A list of DataUpdate instances that will clean up the
         *    database after deletion.
         */
        public function getDeletionUpdates( WikiPage $page,
@@ -486,9 +493,9 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param MagicWord $word the magic word to match
+        * @param MagicWord $word The magic word to match
         *
-        * @return bool whether this Content object matches the given magic word.
+        * @return bool Whether this Content object matches the given magic word.
         */
        public function matchMagicWord( MagicWord $word );
 
@@ -496,9 +503,10 @@ interface Content {
         * Converts this content object into another content object with the given content model,
         * if that is possible.
         *
-        * @param string $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
-        * @param string $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
-        * not allowed, full round-trip conversion is expected to work without losing information.
+        * @param string $toModel The desired content model, use the CONTENT_MODEL_XXX flags.
+        * @param string $lossy Optional flag, set to "lossy" to allow lossy conversion. If lossy
+        * conversion is not allowed, full round-trip conversion is expected to work without losing
+        * information.
         *
         * @return Content|bool A content object with the content model $toModel, or false if
         * that conversion is not supported.
@@ -509,4 +517,5 @@ interface Content {
        //   [11:59] <vvv> Hooks are ugly; make CodeHighlighter interface and a
        //   config to set the class which handles syntax highlighting
        //   [12:00] <vvv> And default it to a DummyHighlighter
+
 }
index 7c51345..defa7da 100644 (file)
@@ -85,10 +85,11 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $content Content|null
-        * @return null|string the textual form of $content, if available
-        * @throws MWException if $content is not an instance of TextContent and
-        *   $wgContentHandlerTextFallback was set to 'fail'.
+        * @param Content $content
+        *
+        * @throws MWException If the content is not an instance of TextContent and
+        * wgContentHandlerTextFallback was set to 'fail'.
+        * @return string|null Textual form of the content, if available.
         */
        public static function getContentText( Content $content = null ) {
                global $wgContentHandlerTextFallback;
@@ -127,24 +128,21 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param string $text the textual representation, will be
+        * @param string $text The textual representation, will be
         *    unserialized to create the Content object
-        * @param $title null|Title the title of the page this text belongs to.
+        * @param Title $title The title of the page this text belongs to.
         *    Required if $modelId is not provided.
-        * @param $modelId null|string the model to deserialize to. If not provided,
+        * @param string $modelId The model to deserialize to. If not provided,
         *    $title->getContentModel() is used.
-        * @param $format null|string the format to use for deserialization. If not
+        * @param string $format The format to use for deserialization. If not
         *    given, the model's default format is used.
         *
-        * @throws MWException
-        * @return Content a Content object representing $text
-        *
-        * @throws MWException if $model or $format is not supported or if $text can
-        *    not be unserialized using $format.
+        * @throws MWException If model ID or format is not supported or if the text can not be
+        * unserialized using the format.
+        * @return Content A Content object representing the text.
         */
        public static function makeContent( $text, Title $title = null,
-               $modelId = null, $format = null
-       ) {
+               $modelId = null, $format = null ) {
                if ( is_null( $modelId ) ) {
                        if ( is_null( $title ) ) {
                                throw new MWException( "Must provide a Title object or a content model ID." );
@@ -188,8 +186,9 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $title Title
-        * @return null|string default model name for the page given by $title
+        * @param Title $title
+        *
+        * @return string Default model name for the page given by $title
         */
        public static function getDefaultModelFor( Title $title ) {
                // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
@@ -253,7 +252,8 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $title Title
+        * @param Title $title
+        *
         * @return ContentHandler
         */
        public static function getForTitle( Title $title ) {
@@ -268,7 +268,8 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $content Content
+        * @param Content $content
+        *
         * @return ContentHandler
         */
        public static function getForContent( Content $content ) {
@@ -303,9 +304,9 @@ abstract class ContentHandler {
         *
         * @param string $modelId The ID of the content model for which to get a
         *    handler. Use CONTENT_MODEL_XXX constants.
-        * @return ContentHandler The ContentHandler singleton for handling the
-        *    model given by $modelId
-        * @throws MWException if no handler is known for $modelId.
+        *
+        * @throws MWException If no handler is known for the model ID.
+        * @return ContentHandler The ContentHandler singleton for handling the model given by the ID.
         */
        public static function getForModelID( $modelId ) {
                global $wgContentHandlers;
@@ -353,8 +354,8 @@ abstract class ContentHandler {
         * @param string $name The content model ID, as given by a CONTENT_MODEL_XXX
         *    constant or returned by Revision::getContentModel().
         *
+        * @throws MWException If the model ID isn't known.
         * @return string The content model's localized name.
-        * @throws MWException if the model id isn't known.
         */
        public static function getLocalizedName( $name ) {
                // Messages: content-model-wikitext, content-model-text,
@@ -389,7 +390,14 @@ abstract class ContentHandler {
 
        // ------------------------------------------------------------------------
 
+       /**
+        * @var string
+        */
        protected $mModelID;
+
+       /**
+        * @var string[]
+        */
        protected $mSupportedFormats;
 
        /**
@@ -398,7 +406,7 @@ abstract class ContentHandler {
         * provided as literals by subclass's constructors.
         *
         * @param string $modelId (use CONTENT_MODEL_XXX constants).
-        * @param array $formats List for supported serialization formats
+        * @param string[] $formats List for supported serialization formats
         *    (typically as MIME types)
         */
        public function __construct( $modelId, $formats ) {
@@ -415,8 +423,9 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $content Content The Content object to serialize
-        * @param $format null|String The desired serialization format
+        * @param Content $content The Content object to serialize
+        * @param string $format The desired serialization format
+        *
         * @return string Serialized form of the content
         */
        abstract public function serializeContent( Content $content, $format = null );
@@ -426,9 +435,10 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param string $blob serialized form of the content
-        * @param $format null|String the format used for serialization
-        * @return Content the Content object created by deserializing $blob
+        * @param string $blob Serialized form of the content
+        * @param string $format The format used for serialization
+        *
+        * @return Content The Content object created by deserializing $blob
         */
        abstract public function unserializeContent( $blob, $format = null );
 
@@ -454,10 +464,10 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param Title $destination the page to redirect to.
-        * @param string $text text to include in the redirect, if possible.
+        * @param Title $destination The page to redirect to.
+        * @param string $text Text to include in the redirect, if possible.
         *
-        * @return Content
+        * @return Content Always null.
         */
        public function makeRedirectContent( Title $destination, $text = '' ) {
                return null;
@@ -469,21 +479,19 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @return String The model ID
+        * @return string The model ID
         */
        public function getModelID() {
                return $this->mModelID;
        }
 
        /**
-        * Throws an MWException if $model_id is not the ID of the content model
-        * supported by this ContentHandler.
-        *
         * @since 1.21
         *
         * @param string $model_id The model to check
         *
-        * @throws MWException
+        * @throws MWException If the model ID is not the ID of the content model supported by this
+        * ContentHandler.
         */
        protected function checkModelID( $model_id ) {
                if ( $model_id !== $this->mModelID ) {
@@ -500,7 +508,7 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @return array of serialization formats as MIME type like strings
+        * @return string[] List of serialization formats as MIME type like strings
         */
        public function getSupportedFormats() {
                return $this->mSupportedFormats;
@@ -515,7 +523,7 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @return string the name of the default serialization format as a MIME type
+        * @return string The name of the default serialization format as a MIME type
         */
        public function getDefaultFormat() {
                return $this->mSupportedFormats[0];
@@ -530,11 +538,11 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param string $format the serialization format to check
+        * @param string $format The serialization format to check
+        *
         * @return bool
         */
        public function isSupportedFormat( $format ) {
-
                if ( !$format ) {
                        return true; // this means "use the default"
                }
@@ -543,13 +551,11 @@ abstract class ContentHandler {
        }
 
        /**
-        * Throws an MWException if isSupportedFormat( $format ) is not true.
-        * Convenient for checking whether a format provided as a parameter is
-        * actually supported.
+        * Convenient for checking whether a format provided as a parameter is actually supported.
         *
-        * @param string $format the serialization format to check
+        * @param string $format The serialization format to check
         *
-        * @throws MWException
+        * @throws MWException If the format is not supported by this content handler.
         */
        protected function checkFormat( $format ) {
                if ( !$this->isSupportedFormat( $format ) ) {
@@ -568,7 +574,7 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @return Array
+        * @return array Always an empty array.
         */
        public function getActionOverrides() {
                return array();
@@ -579,21 +585,18 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $context IContextSource context to use, anything else will be
-        *    ignored
-        * @param $old Integer Old ID we want to show and diff with.
-        * @param int|string $new String either 'prev' or 'next'.
-        * @param $rcid Integer ??? FIXME (default 0)
-        * @param $refreshCache boolean If set, refreshes the diff cache
-        * @param $unhide boolean If set, allow viewing deleted revs
+        * @param IContextSource $context Context to use, anything else will be ignored.
+        * @param int $old Revision ID we want to show and diff with.
+        * @param int|string $new Either a revision ID or one of the strings 'cur', 'prev' or 'next'.
+        * @param int $rcid FIXME: Deprecated, no longer used. Defaults to 0.
+        * @param bool $refreshCache If set, refreshes the diff cache. Defaults to false.
+        * @param bool $unhide If set, allow viewing deleted revs. Defaults to false.
         *
         * @return DifferenceEngine
         */
-       public function createDifferenceEngine( IContextSource $context,
-               $old = 0, $new = 0,
-               $rcid = 0, # FIXME: use everywhere!
-               $refreshCache = false, $unhide = false
-       ) {
+       public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
+               $rcid = 0, //FIXME: Deprecated, no longer used
+               $refreshCache = false, $unhide = false ) {
                $diffEngineClass = $this->getDiffEngineClass();
 
                return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
@@ -613,10 +616,10 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param Title $title the page to determine the language for.
-        * @param Content|null $content the page's content, if you have it handy, to avoid reloading it.
+        * @param Title $title The page to determine the language for.
+        * @param Content $content The page's content, if you have it handy, to avoid reloading it.
         *
-        * @return Language the page's language
+        * @return Language The page's language
         */
        public function getPageLanguage( Title $title, Content $content = null ) {
                global $wgContLang, $wgLang;
@@ -648,10 +651,10 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param Title $title the page to determine the language for.
-        * @param Content|null $content the page's content, if you have it handy, to avoid reloading it.
+        * @param Title $title The page to determine the language for.
+        * @param Content $content The page's content, if you have it handy, to avoid reloading it.
         *
-        * @return Language the page's language for viewing
+        * @return Language The page's language for viewing
         */
        public function getPageViewLanguage( Title $title, Content $content = null ) {
                $pageLang = $this->getPageLanguage( $title, $content );
@@ -680,9 +683,9 @@ abstract class ContentHandler {
         * @note: this calls the ContentHandlerCanBeUsedOn hook which may be used to override which
         * content model can be used where.
         *
-        * @param Title $title the page's title.
+        * @param Title $title The page's title.
         *
-        * @return bool true if content of this kind can be used on the given page, false otherwise.
+        * @return bool True if content of this kind can be used on the given page, false otherwise.
         */
        public function canBeUsedOn( Title $title ) {
                $ok = true;
@@ -704,19 +707,18 @@ abstract class ContentHandler {
        }
 
        /**
-        * Attempts to merge differences between three versions.
-        * Returns a new Content object for a clean merge and false for failure or
-        * a conflict.
+        * Attempts to merge differences between three versions. Returns a new
+        * Content object for a clean merge and false for failure or a conflict.
         *
         * This default implementation always returns false.
         *
         * @since 1.21
         *
-        * @param $oldContent Content|string  String
-        * @param $myContent Content|string   String
-        * @param $yourContent Content|string String
+        * @param Content|string $oldContent The page's previous content.
+        * @param Content|string $myContent One of the page's conflicting contents.
+        * @param Content|string $yourContent One of the page's conflicting contents.
         *
-        * @return Content|Bool
+        * @return Content|bool Always false.
         */
        public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
                return false;
@@ -727,13 +729,14 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $oldContent Content|null: the previous text of the page.
-        * @param $newContent Content|null: The submitted text of the page.
+        * @param Content $oldContent The previous text of the page.
+        * @param Content $newContent The submitted text of the page.
         * @param int $flags Bit mask: a bit mask of flags submitted for the edit.
         *
         * @return string An appropriate auto-summary, or an empty string.
         */
-       public function getAutosummary( Content $oldContent = null, Content $newContent = null, $flags ) {
+       public function getAutosummary( Content $oldContent = null, Content $newContent = null,
+               $flags ) {
                // Decide what kind of auto-summary is needed.
 
                // Redirect auto-summaries
@@ -799,8 +802,9 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $title Title: the page's title
-        * @param &$hasHistory Boolean: whether the page has a history
+        * @param Title $title The page's title
+        * @param bool &$hasHistory Whether the page has a history
+        *
         * @return mixed String containing deletion reason or empty string, or
         *    boolean false if no revision occurred
         *
@@ -907,9 +911,9 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param $current Revision The current text
-        * @param $undo Revision The revision to undo
-        * @param $undoafter Revision Must be an earlier revision than $undo
+        * @param Revision $current The current text
+        * @param Revision $undo The revision to undo
+        * @param Revision $undoafter Must be an earlier revision than $undo
         *
         * @return mixed String on success, false on failure
         */
@@ -980,7 +984,7 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @return bool
+        * @return bool Always false.
         */
        public function isParserCacheSupported() {
                return false;
@@ -993,7 +997,7 @@ abstract class ContentHandler {
         * Content models that return true here should also implement
         * Content::getSection, Content::replaceSection, etc. to handle sections..
         *
-        * @return boolean whether sections are supported.
+        * @return bool Always false.
         */
        public function supportsSections() {
                return false;
@@ -1006,7 +1010,7 @@ abstract class ContentHandler {
         * Content models that return true here should also implement
         * ContentHandler::makeRedirectContent to return a Content object.
         *
-        * @return boolean whether redirects are supported.
+        * @return bool Always false.
         */
        public function supportsRedirects() {
                return false;
@@ -1038,13 +1042,13 @@ abstract class ContentHandler {
         * hook function, a new Content object is constructed from the new
         * text.
         *
-        * @param string $event event name
-        * @param array $args parameters passed to hook functions
-        * @param bool $warn whether to log a warning.
+        * @param string $event Event name
+        * @param array $args Parameters passed to hook functions
+        * @param bool $warn Whether to log a warning.
         *                    Default to self::$enableDeprecationWarnings.
         *                    May be set to false for testing.
         *
-        * @return Boolean True if no handler aborted the hook
+        * @return bool True if no handler aborted the hook
         *
         * @see ContentHandler::$enableDeprecationWarnings
         */
index 03cc2d0..5fc2c9f 100644 (file)
  * @ingroup Content
  */
 class CssContent extends TextContent {
+
+       /**
+        * @param string $text CSS code.
+        */
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_CSS );
        }
@@ -39,10 +43,13 @@ class CssContent extends TextContent {
         * Returns a Content object with pre-save transformations applied using
         * Parser::preSaveTransform().
         *
-        * @param $title Title
-        * @param $user User
-        * @param $popts ParserOptions
-        * @return Content
+        * @param Title $title
+        * @param User $user
+        * @param ParserOptions $popts
+        *
+        * @return CssContent
+        *
+        * @see TextContent::preSaveTransform
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
                global $wgParser;
@@ -54,6 +61,9 @@ class CssContent extends TextContent {
                return new CssContent( $pst );
        }
 
+       /**
+        * @return string CSS wrapped in a <pre> tag.
+        */
        protected function getHtml() {
                $html = "";
                $html .= "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n";
@@ -62,4 +72,5 @@ class CssContent extends TextContent {
 
                return $html;
        }
+
 }
index 7becabb..85059a8 100644 (file)
  * @ingroup Content
  */
 class CssContentHandler extends TextContentHandler {
+
+       /**
+        * @param string $modelId
+        */
        public function __construct( $modelId = CONTENT_MODEL_CSS ) {
                parent::__construct( $modelId, array( CONTENT_FORMAT_CSS ) );
        }
 
+       /**
+        * @param string $text
+        * @param string $format
+        *
+        * @return CssContent
+        *
+        * @see ContentHandler::unserializeContent()
+        */
        public function unserializeContent( $text, $format = null ) {
                $this->checkFormat( $format );
 
                return new CssContent( $text );
        }
 
+       /**
+        * @return CssContent A new CssContent object with empty text.
+        *
+        * @see ContentHandler::makeEmptyContent()
+        */
        public function makeEmptyContent() {
                return new CssContent( '' );
        }
@@ -47,6 +64,7 @@ class CssContentHandler extends TextContentHandler {
         *
         * @param Title $title
         * @param Content $content
+        *
         * @return Language wfGetLangObj( 'en' )
         *
         * @see ContentHandler::getPageLanguage()
@@ -60,6 +78,7 @@ class CssContentHandler extends TextContentHandler {
         *
         * @param Title $title
         * @param Content $content
+        *
         * @return Language wfGetLangObj( 'en' )
         *
         * @see ContentHandler::getPageViewLanguage()
@@ -67,4 +86,5 @@ class CssContentHandler extends TextContentHandler {
        public function getPageViewLanguage( Title $title, Content $content = null ) {
                return wfGetLangObj( 'en' );
        }
+
 }
index 2ae572b..11a470e 100644 (file)
  * @ingroup Content
  */
 class JavaScriptContent extends TextContent {
+
+       /**
+        * @param string $text JavaScript code.
+        */
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_JAVASCRIPT );
        }
@@ -42,7 +46,8 @@ class JavaScriptContent extends TextContent {
         * @param Title $title
         * @param User $user
         * @param ParserOptions $popts
-        * @return Content
+        *
+        * @return JavaScriptContent
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
                global $wgParser;
@@ -55,6 +60,9 @@ class JavaScriptContent extends TextContent {
                return new JavaScriptContent( $pst );
        }
 
+       /**
+        * @return string JavaScript wrapped in a <pre> tag.
+        */
        protected function getHtml() {
                $html = "";
                $html .= "<pre class=\"mw-code mw-js\" dir=\"ltr\">\n";
@@ -63,4 +71,5 @@ class JavaScriptContent extends TextContent {
 
                return $html;
        }
+
 }
index 064c422..2e98976 100644 (file)
  * @todo make ScriptContentHandler base class, do highlighting stuff there?
  */
 class JavaScriptContentHandler extends TextContentHandler {
+
+       /**
+        * @param string $modelId
+        */
        public function __construct( $modelId = CONTENT_MODEL_JAVASCRIPT ) {
                parent::__construct( $modelId, array( CONTENT_FORMAT_JAVASCRIPT ) );
        }
 
+       /**
+        * @param string $text
+        * @param string $format
+        *
+        * @return JavaScriptContent
+        *
+        * @see ContentHandler::unserializeContent()
+        */
        public function unserializeContent( $text, $format = null ) {
                $this->checkFormat( $format );
 
                return new JavaScriptContent( $text );
        }
 
+       /**
+        * @return JavaScriptContent A new JavaScriptContent object with empty text.
+        *
+        * @see ContentHandler::makeEmptyContent()
+        */
        public function makeEmptyContent() {
                return new JavaScriptContent( '' );
        }
@@ -47,6 +64,7 @@ class JavaScriptContentHandler extends TextContentHandler {
         *
         * @param Title $title
         * @param Content $content
+        *
         * @return Language wfGetLangObj( 'en' )
         *
         * @see ContentHandler::getPageLanguage()
@@ -60,6 +78,7 @@ class JavaScriptContentHandler extends TextContentHandler {
         *
         * @param Title $title
         * @param Content $content
+        *
         * @return Language wfGetLangObj( 'en' )
         *
         * @see ContentHandler::getPageViewLanguage()
@@ -67,4 +86,5 @@ class JavaScriptContentHandler extends TextContentHandler {
        public function getPageViewLanguage( Title $title, Content $content = null ) {
                return wfGetLangObj( 'en' );
        }
+
 }
index e780846..b601344 100644 (file)
  * @ingroup Content
  */
 class MessageContent extends AbstractContent {
+
        /**
         * @var Message
         */
        protected $mMessage;
 
        /**
-        * @param Message|String $msg A Message object, or a message key
-        * @param array|null $params An optional array of message parameters
+        * @param Message|string $msg A Message object, or a message key.
+        * @param string[] $params An optional array of message parameters.
         */
        public function __construct( $msg, $params = null ) {
                # XXX: messages may be wikitext, html or plain text! and maybe even something else entirely.
@@ -59,18 +60,18 @@ class MessageContent extends AbstractContent {
        }
 
        /**
-        * Returns the message as rendered HTML
+        * Fully parse the text from wikitext to HTML.
         *
-        * @return string The message text, parsed into html
+        * @return string Parsed HTML.
         */
        public function getHtml() {
                return $this->mMessage->parse();
        }
 
        /**
-        * Returns the message as rendered HTML
+        * Returns the message text. {{-transformation is done.
         *
-        * @return string The message text, parsed into html
+        * @return string Unescaped message text.
         */
        public function getWikitext() {
                return $this->mMessage->text();
@@ -87,6 +88,8 @@ class MessageContent extends AbstractContent {
        }
 
        /**
+        * @return string
+        *
         * @see Content::getTextForSearchIndex
         */
        public function getTextForSearchIndex() {
@@ -94,6 +97,8 @@ class MessageContent extends AbstractContent {
        }
 
        /**
+        * @return string
+        *
         * @see Content::getWikitextForTransclusion
         */
        public function getWikitextForTransclusion() {
@@ -101,6 +106,10 @@ class MessageContent extends AbstractContent {
        }
 
        /**
+        * @param int $maxLength Maximum length of the summary text, defaults to 250.
+        *
+        * @return string The summary text.
+        *
         * @see Content::getTextForSummary
         */
        public function getTextForSummary( $maxlength = 250 ) {
@@ -108,18 +117,18 @@ class MessageContent extends AbstractContent {
        }
 
        /**
-        * @see Content::getSize
-        *
         * @return int
+        *
+        * @see Content::getSize
         */
        public function getSize() {
                return strlen( $this->mMessage->plain() );
        }
 
        /**
-        * @see Content::copy
-        *
         * @return Content. A copy of this object
+        *
+        * @see Content::copy
         */
        public function copy() {
                // MessageContent is immutable (because getNativeData() returns a clone of the Message object)
@@ -127,29 +136,28 @@ class MessageContent extends AbstractContent {
        }
 
        /**
-        * @see Content::isCountable
-        *
         * @param bool $hasLinks
-        * @return bool false
+        *
+        * @return bool Always false.
+        *
+        * @see Content::isCountable
         */
        public function isCountable( $hasLinks = null ) {
                return false;
        }
 
        /**
-        * @see Content::getParserOutput
+        * @param Title $title Unused.
+        * @param int $revId Unused.
+        * @param ParserOptions $options Unused.
+        * @param bool $generateHtml Whether to generate HTML (default: true).
         *
-        * @param Title $title
-        * @param int $revId Optional revision ID
-        * @param ParserOptions $options
-        * @param bool $generateHtml Wether to generate HTML
         * @return ParserOutput
+        *
+        * @see Content::getParserOutput
         */
-       public function getParserOutput(
-               Title $title, $revId = null,
-               ParserOptions $options = null, $generateHtml = true
-       ) {
-
+       public function getParserOutput( Title $title, $revId = null,
+               ParserOptions $options = null, $generateHtml = true ) {
                if ( $generateHtml ) {
                        $html = $this->getHtml();
                } else {
@@ -160,4 +168,5 @@ class MessageContent extends AbstractContent {
 
                return $po;
        }
+
 }
index 068b150..b0da62d 100644 (file)
  * @ingroup Content
  */
 class TextContent extends AbstractContent {
+
+       /**
+        * @param string $text
+        * @param string $model_id
+        */
        public function __construct( $text, $model_id = CONTENT_MODEL_TEXT ) {
                parent::__construct( $model_id );
 
@@ -50,6 +55,11 @@ class TextContent extends AbstractContent {
                $this->mText = $text;
        }
 
+       /**
+        * @note Mutable subclasses MUST override this to return a copy!
+        *
+        * @return Content $this
+        */
        public function copy() {
                return $this; # NOTE: this is ok since TextContent are immutable.
        }
@@ -81,10 +91,10 @@ class TextContent extends AbstractContent {
         * Returns true if this content is not a redirect, and $wgArticleCountMethod
         * is "any".
         *
-        * @param bool $hasLinks if it is known whether this content contains links,
+        * @param bool $hasLinks If it is known whether this content contains links,
         * provide this information here, to avoid redundant parsing to find out.
         *
-        * @return bool True if the content is countable
+        * @return bool
         */
        public function isCountable( $hasLinks = null ) {
                global $wgArticleCountMethod;
@@ -103,7 +113,7 @@ class TextContent extends AbstractContent {
        /**
         * Returns the text represented by this Content object, as a string.
         *
-        * @return string: the raw text
+        * @return string The raw text.
         */
        public function getNativeData() {
                $text = $this->mText;
@@ -114,7 +124,7 @@ class TextContent extends AbstractContent {
        /**
         * Returns the text represented by this Content object, as a string.
         *
-        * @return string: the raw text
+        * @return string The raw text.
         */
        public function getTextForSearchIndex() {
                return $this->getNativeData();
@@ -126,7 +136,7 @@ class TextContent extends AbstractContent {
         *
         * @note: this allows any text-based content to be transcluded as if it was wikitext.
         *
-        * @return string|false: the raw text, or null if the conversion failed
+        * @return string|false The raw text, or false if the conversion failed.
         */
        public function getWikitextForTransclusion() {
                $wikitext = $this->convert( CONTENT_MODEL_WIKITEXT, 'lossy' );
@@ -142,9 +152,10 @@ class TextContent extends AbstractContent {
         * Returns a Content object with pre-save transformations applied.
         * This implementation just trims trailing whitespace.
         *
-        * @param $title Title
-        * @param $user User
-        * @param $popts ParserOptions
+        * @param Title $title
+        * @param User $user
+        * @param ParserOptions $popts
+        *
         * @return Content
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
@@ -159,9 +170,9 @@ class TextContent extends AbstractContent {
         *
         * @since 1.21
         *
-        * @param $that Content: The other content object to compare this content
+        * @param Content $that The other content object to compare this content
         * object to.
-        * @param $lang Language: The language object to use for text segmentation.
+        * @param Language $lang The language object to use for text segmentation.
         *    If not given, $wgContentLang is used.
         *
         * @return Diff A diff representing the changes that would have to be
@@ -194,17 +205,15 @@ class TextContent extends AbstractContent {
         * Returns a generic ParserOutput object, wrapping the HTML returned by
         * getHtml().
         *
-        * @param $title Title Context title for parsing
-        * @param int|null $revId Revision ID (for {{REVISIONID}})
-        * @param $options ParserOptions|null Parser options
+        * @param Title $title Context title for parsing
+        * @param int $revId Revision ID (for {{REVISIONID}})
+        * @param ParserOptions $options Parser options
         * @param bool $generateHtml Whether or not to generate HTML
         *
-        * @return ParserOutput representing the HTML form of the text
+        * @return ParserOutput Representing the HTML form of the text.
         */
-       public function getParserOutput( Title $title,
-               $revId = null,
-               ParserOptions $options = null, $generateHtml = true
-       ) {
+       public function getParserOutput( Title $title, $revId = null,
+               ParserOptions $options = null, $generateHtml = true ) {
                global $wgParser, $wgTextModelsToParse;
 
                if ( !$options ) {
@@ -249,7 +258,7 @@ class TextContent extends AbstractContent {
         * Generates a syntax-highlighted version of the content, as HTML.
         * Used by the default implementation of getHtml().
         *
-        * @return string an HTML representation of the content's markup
+        * @return string A HTML representation of the content's markup
         */
        protected function getHighlightHtml() {
                # TODO: make Highlighter interface, use highlighter here, if available
@@ -257,17 +266,15 @@ class TextContent extends AbstractContent {
        }
 
        /**
-        * @see Content::convert()
-        *
         * This implementation provides lossless conversion between content models based
         * on TextContent.
         *
-        * @param string $toModel the desired content model, use the CONTENT_MODEL_XXX flags.
-        * @param string $lossy flag, set to "lossy" to allow lossy conversion. If lossy conversion is
-        * not allowed, full round-trip conversion is expected to work without losing information.
+        * @param string $toModel
+        * @param string $lossy
         *
-        * @return Content|bool A content object with the content model $toModel, or false if
-        * that conversion is not supported.
+        * @return Content|bool
+        *
+        * @see Content::convert()
         */
        public function convert( $toModel, $lossy = '' ) {
                $converted = parent::convert( $toModel, $lossy );
@@ -286,4 +293,5 @@ class TextContent extends AbstractContent {
 
                return $converted;
        }
+
 }
index 94b5c57..b728d31 100644 (file)
  * @ingroup Content
  */
 class TextContentHandler extends ContentHandler {
+
        // @codingStandardsIgnoreStart bug 57585
        public function __construct( $modelId = CONTENT_MODEL_TEXT,
-               $formats = array( CONTENT_FORMAT_TEXT )
-       ) {
+               $formats = array( CONTENT_FORMAT_TEXT ) ) {
                parent::__construct( $modelId, $formats );
        }
        // @codingStandardsIgnoreEnd
@@ -40,8 +40,9 @@ class TextContentHandler extends ContentHandler {
        /**
         * Returns the content's text as-is.
         *
-        * @param $content Content
-        * @param $format string|null
+        * @param Content $content
+        * @param string $format The serialization format to check
+        *
         * @return mixed
         */
        public function serializeContent( Content $content, $format = null ) {
@@ -59,11 +60,11 @@ class TextContentHandler extends ContentHandler {
         *
         * This text-based implementation uses wfMerge().
         *
-        * @param $oldContent Content|string  String
-        * @param $myContent Content|string   String
-        * @param $yourContent Content|string String
+        * @param Content|string $oldContent The page's previous content.
+        * @param Content|string $myContent One of the page's conflicting contents.
+        * @param Content|string $yourContent One of the page's conflicting contents.
         *
-        * @return Content|Bool
+        * @return Content|bool
         */
        public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
                $this->checkModelID( $oldContent->getModel() );
@@ -96,10 +97,10 @@ class TextContentHandler extends ContentHandler {
         *
         * @since 1.21
         *
-        * @param $text   string serialized form of the content
-        * @param $format null|String the format used for serialization
+        * @param string $text Serialized form of the content
+        * @param string $format The format used for serialization
         *
-        * @return Content the TextContent object wrapping $text
+        * @return Content The TextContent object wrapping $text
         */
        public function unserializeContent( $text, $format = null ) {
                $this->checkFormat( $format );
@@ -112,9 +113,10 @@ class TextContentHandler extends ContentHandler {
         *
         * @since 1.21
         *
-        * @return Content
+        * @return Content A new TextContent object with empty text.
         */
        public function makeEmptyContent() {
                return new TextContent( '' );
        }
+
 }
index f495c56..605222e 100644 (file)
  * @ingroup Content
  */
 class WikitextContent extends TextContent {
+
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
        }
 
        /**
+        * @param string $section
+        *
+        * @return Content|bool|null
+        *
         * @see Content::getSection()
         */
        public function getSection( $section ) {
@@ -52,6 +57,13 @@ class WikitextContent extends TextContent {
        }
 
        /**
+        * @param string $section
+        * @param Content $with
+        * @param string $sectionTitle
+        *
+        * @throws MWException
+        * @return Content
+        *
         * @see Content::replaceSection()
         */
        public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
@@ -103,7 +115,8 @@ class WikitextContent extends TextContent {
         * Returns a new WikitextContent object with the given section heading
         * prepended.
         *
-        * @param $header string
+        * @param string $header
+        *
         * @return Content
         */
        public function addSectionHeader( $header ) {
@@ -119,9 +132,10 @@ class WikitextContent extends TextContent {
         * Returns a Content object with pre-save transformations applied using
         * Parser::preSaveTransform().
         *
-        * @param $title Title
-        * @param $user User
-        * @param $popts ParserOptions
+        * @param Title $title
+        * @param User $user
+        * @param ParserOptions $popts
+        *
         * @return Content
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
@@ -138,8 +152,9 @@ class WikitextContent extends TextContent {
         * Returns a Content object with preload transformations applied (or this
         * object if no transformations apply).
         *
-        * @param $title Title
-        * @param $popts ParserOptions
+        * @param Title $title
+        * @param ParserOptions $popts
+        *
         * @return Content
         */
        public function preloadTransform( Title $title, ParserOptions $popts ) {
@@ -157,7 +172,8 @@ class WikitextContent extends TextContent {
         * @note: migrated here from Title::newFromRedirectInternal()
         *
         * @since 1.23
-        * @return array 2 elements: Title|null and string
+        *
+        * @return array List of two elements: Title|null and string.
         */
        protected function getRedirectTargetAndText() {
                global $wgMaxRedirects;
@@ -195,10 +211,9 @@ class WikitextContent extends TextContent {
        /**
         * Implement redirect extraction for wikitext.
         *
-        * @return null|Title
+        * @return Title|null
         *
         * @see Content::getRedirectTarget
-        * @see AbstractContent::getRedirectTarget
         */
        public function getRedirectTarget() {
                list( $title, ) = $this->getRedirectTargetAndText();
@@ -207,8 +222,6 @@ class WikitextContent extends TextContent {
        }
 
        /**
-        * @see Content::updateRedirect()
-        *
         * This implementation replaces the first link on the page with the given new target
         * if this Content object is a redirect. Otherwise, this method returns $this.
         *
@@ -216,8 +229,9 @@ class WikitextContent extends TextContent {
         *
         * @param Title $target
         *
-        * @return Content a new Content object with the updated redirect (or $this
-        *   if this Content object isn't a redirect)
+        * @return Content
+        *
+        * @see Content::updateRedirect()
         */
        public function updateRedirect( Title $target ) {
                if ( !$this->isRedirect() ) {
@@ -238,14 +252,14 @@ class WikitextContent extends TextContent {
         * Returns true if this content is not a redirect, and this content's text
         * is countable according to the criteria defined by $wgArticleCountMethod.
         *
-        * @param bool $hasLinks if it is known whether this content contains
+        * @param bool $hasLinks If it is known whether this content contains
         *    links, provide this information here, to avoid redundant parsing to
         *    find out (default: null).
-        * @param $title Title: (default: null)
+        * @param Title $title Optional title, defaults to the title from the current main request.
         *
         * @internal param \IContextSource $context context for parsing if necessary
         *
-        * @return bool True if the content is countable
+        * @return bool
         */
        public function isCountable( $hasLinks = null, Title $title = null ) {
                global $wgArticleCountMethod;
@@ -279,6 +293,10 @@ class WikitextContent extends TextContent {
                return false;
        }
 
+       /**
+        * @param int $maxlength
+        * @return string
+        */
        public function getTextForSummary( $maxlength = 250 ) {
                $truncatedtext = parent::getTextForSummary( $maxlength );
 
@@ -294,20 +312,17 @@ class WikitextContent extends TextContent {
         * Returns a ParserOutput object resulting from parsing the content's text
         * using $wgParser.
         *
-        * @since    1.21
+        * @since 1.21
         *
-        * @param $title Title
-        * @param int $revId Revision to pass to the parser (default: null)
-        * @param $options ParserOptions (default: null)
+        * @param Title $title * @param int $revId Revision to pass to the parser (default: null)
+        * @param ParserOptions $options (default: null)
         * @param bool $generateHtml (default: false)
-        *
         * @internal param \IContextSource|null $context
-        * @return ParserOutput representing the HTML form of the text
+        *
+        * @return ParserOutput Representing the HTML form of the text
         */
-       public function getParserOutput( Title $title,
-               $revId = null,
-               ParserOptions $options = null, $generateHtml = true
-       ) {
+       public function getParserOutput( Title $title, $revId = null,
+               ParserOptions $options = null, $generateHtml = true ) {
                global $wgParser;
 
                if ( !$options ) {
@@ -334,6 +349,9 @@ class WikitextContent extends TextContent {
                return $po;
        }
 
+       /**
+        * @throws MWException
+        */
        protected function getHtml() {
                throw new MWException(
                        "getHtml() not implemented for wikitext. "
@@ -342,15 +360,16 @@ class WikitextContent extends TextContent {
        }
 
        /**
-        * @see  Content::matchMagicWord()
-        *
         * This implementation calls $word->match() on the this TextContent object's text.
         *
         * @param MagicWord $word
         *
-        * @return bool whether this Content object matches the given magic word.
+        * @return bool
+        *
+        * @see Content::matchMagicWord()
         */
        public function matchMagicWord( MagicWord $word ) {
                return $word->match( $this->getNativeData() );
        }
+
 }
index 1e8fd05..5ae3e25 100644 (file)
@@ -29,6 +29,7 @@
  * @ingroup Content
  */
 class WikitextContentHandler extends TextContentHandler {
+
        public function __construct( $modelId = CONTENT_MODEL_WIKITEXT ) {
                parent::__construct( $modelId, array( CONTENT_FORMAT_WIKITEXT ) );
        }
@@ -40,9 +41,9 @@ class WikitextContentHandler extends TextContentHandler {
        }
 
        /**
-        * @see ContentHandler::makeEmptyContent
+        * @return Content A new WikitextContent object with empty text.
         *
-        * @return Content
+        * @see ContentHandler::makeEmptyContent
         */
        public function makeEmptyContent() {
                return new WikitextContent( '' );
@@ -51,12 +52,12 @@ class WikitextContentHandler extends TextContentHandler {
        /**
         * Returns a WikitextContent object representing a redirect to the given destination page.
         *
-        * @see ContentHandler::makeRedirectContent
-        *
-        * @param Title $destination the page to redirect to.
-        * @param string $text text to include in the redirect, if possible.
+        * @param Title $destination The page to redirect to.
+        * @param string $text Text to include in the redirect, if possible.
         *
         * @return Content
+        *
+        * @see ContentHandler::makeRedirectContent
         */
        public function makeRedirectContent( Title $destination, $text = '' ) {
                $optionalColon = '';
@@ -84,9 +85,9 @@ class WikitextContentHandler extends TextContentHandler {
        /**
         * Returns true because wikitext supports redirects.
         *
-        * @see ContentHandler::supportsRedirects
+        * @return bool Always true.
         *
-        * @return boolean whether redirects are supported.
+        * @see ContentHandler::supportsRedirects
         */
        public function supportsRedirects() {
                return true;
@@ -95,7 +96,9 @@ class WikitextContentHandler extends TextContentHandler {
        /**
         * Returns true because wikitext supports sections.
         *
-        * @return boolean whether sections are supported.
+        * @return bool Always true.
+        *
+        * @see ContentHandler::supportsSections
         */
        public function supportsSections() {
                return true;
@@ -106,9 +109,13 @@ class WikitextContentHandler extends TextContentHandler {
         * ParserCache mechanism.
         *
         * @since 1.21
-        * @return bool
+        *
+        * @return bool Always true.
+        *
+        * @see ContentHandler::isParserCacheSupported
         */
        public function isParserCacheSupported() {
                return true;
        }
+
 }
index 543ee18..c12b76a 100644 (file)
@@ -32,7 +32,8 @@ class ArrayDiffFormatter extends DiffFormatter {
 
        /**
         * @param Diff $diff A Diff object.
-        * @return array
+        *
+        * @return array[] List of associative arrays, each describing a difference.
         */
        public function format( $diff ) {
                $oldline = 1;
@@ -77,4 +78,5 @@ class ArrayDiffFormatter extends DiffFormatter {
 
                return $retval;
        }
+
 }
index 351a9dd..61edc1e 100644 (file)
  */
 abstract class DiffOp {
 
+       /**
+        * @var string
+        */
        public $type;
+
+       /**
+        * @var string[]
+        */
        public $orig;
+
+       /**
+        * @var string[]
+        */
        public $closing;
 
+       /**
+        * @return string
+        */
        public function getType() {
                return $this->type;
        }
 
+       /**
+        * @return string[]
+        */
        public function getOrig() {
                return $this->orig;
        }
 
+       /**
+        * @param int $i
+        * @return string|null
+        */
        public function getClosing( $i = null ) {
                if( $i === null ) {
                        return $this->closing;
@@ -195,9 +216,10 @@ class DiffEngine {
        protected $lcs = 0;
 
        /**
-        * @param $from_lines
-        * @param $to_lines
-        * @return array
+        * @param string[] $from_lines
+        * @param string[] $to_lines
+        *
+        * @return DiffOp[]
         */
        public function diff( $from_lines, $to_lines ) {
                wfProfileIn( __METHOD__ );
@@ -256,8 +278,8 @@ class DiffEngine {
        }
 
        /**
-        * @param $from_lines
-        * @param $to_lines
+        * @param string[] $from_lines
+        * @param string[] $to_lines
         */
        private function diffLocal( $from_lines, $to_lines ) {
                global $wgExternalDiffEngine;
@@ -329,7 +351,9 @@ class DiffEngine {
 
        /**
         * Returns the whole line if it's small enough, or the MD5 hash otherwise
-        * @param $line string
+        *
+        * @param string $line
+        *
         * @return string
         */
        private function lineHash( $line ) {
@@ -356,12 +380,14 @@ class DiffEngine {
         * of the two files do not match, and likewise that the last lines do not
         * match.  The caller must trim matching lines from the beginning and end
         * of the portions it is going to specify.
-        * @param $xoff
-        * @param $xlim
-        * @param $yoff
-        * @param $ylim
-        * @param $nchunks
-        * @return array
+        *
+        * @param int $xoff
+        * @param int $xlim
+        * @param int $yoff
+        * @param int $ylim
+        * @param int $nchunks
+        *
+        * @return array List of two elements, integer and array[].
         */
        private function diag( $xoff, $xlim, $yoff, $ylim, $nchunks ) {
                $flip = false;
@@ -398,7 +424,7 @@ class DiffEngine {
                        }
 
                        $x1 = $xoff + (int)( ( $numer + ( $xlim - $xoff ) * $chunk ) / $nchunks );
-                       for ( ; $x < $x1; $x++ ) {
+                       for (; $x < $x1; $x++ ) {
                                $line = $flip ? $this->yv[$x] : $this->xv[$x];
                                if ( empty( $ymatches[$line] ) ) {
                                        continue;
@@ -446,7 +472,8 @@ class DiffEngine {
        }
 
        /**
-        * @param $ypos
+        * @param int $ypos
+        *
         * @return int
         */
        private function lcsPos( $ypos ) {
@@ -488,10 +515,11 @@ class DiffEngine {
         *
         * Note that XLIM, YLIM are exclusive bounds.
         * All line numbers are origin-0 and discarded lines are not counted.
-        * @param $xoff
-        * @param $xlim
-        * @param $yoff
-        * @param $ylim
+        *
+        * @param int $xoff
+        * @param int $xlim
+        * @param int $yoff
+        * @param int $ylim
         */
        private function compareSeq( $xoff, $xlim, $yoff, $ylim ) {
                // Slide down the bottom initial diagonal.
@@ -688,9 +716,9 @@ class Diff {
         * Constructor.
         * Computes diff between sequences of strings.
         *
-        * @param $from_lines array An array of strings.
+        * @param string[] $from_lines An array of strings.
         *   Typically these are lines from a file.
-        * @param $to_lines array An array of strings.
+        * @param string[] $to_lines An array of strings.
         */
        public function __construct( $from_lines, $to_lines ) {
                $eng = new DiffEngine;
@@ -698,7 +726,7 @@ class Diff {
        }
 
        /**
-        * @return array|DiffOp[]
+        * @return DiffOp[]
         */
        public function getEdits() {
                return $this->edits;
@@ -711,6 +739,7 @@ class Diff {
         *
         *    $diff = new Diff($lines1, $lines2);
         *    $rev = $diff->reverse();
+        *
         * @return Object A Diff object representing the inverse of the
         *   original diff.
         */
@@ -764,7 +793,7 @@ class Diff {
         * This reconstructs the $from_lines parameter passed to the
         * constructor.
         *
-        * @return array The original sequence of strings.
+        * @return string[] The original sequence of strings.
         */
        public function orig() {
                $lines = array();
@@ -784,7 +813,7 @@ class Diff {
         * This reconstructs the $to_lines parameter passed to the
         * constructor.
         *
-        * @return array The sequence of strings.
+        * @return string[] The sequence of strings.
         */
        public function closing() {
                $lines = array();
@@ -814,18 +843,15 @@ class MappedDiff extends Diff {
         * case-insensitve diffs, or diffs which ignore
         * changes in white-space.
         *
-        * @param $from_lines array An array of strings.
+        * @param string[] $from_lines An array of strings.
         *   Typically these are lines from a file.
-        *
-        * @param $to_lines array An array of strings.
-        *
-        * @param $mapped_from_lines array This array should
+        * @param string[] $to_lines An array of strings.
+        * @param string[] $mapped_from_lines This array should
         *   have the same size number of elements as $from_lines.
         *   The elements in $mapped_from_lines and
         *   $mapped_to_lines are what is actually compared
         *   when computing the diff.
-        *
-        * @param $mapped_to_lines array This array should
+        * @param string[] $mapped_to_lines This array should
         *   have the same number of elements as $to_lines.
         */
        public function __construct( $from_lines, $to_lines,
@@ -875,7 +901,7 @@ class HWLDFWordAccumulator {
        private $tag = '';
 
        /**
-        * @param $new_tag
+        * @param string $new_tag
         */
        private function flushGroup( $new_tag ) {
                if ( $this->group !== '' ) {
@@ -894,7 +920,7 @@ class HWLDFWordAccumulator {
        }
 
        /**
-        * @param $new_tag
+        * @param string $new_tag
         */
        private function flushLine( $new_tag ) {
                $this->flushGroup( $new_tag );
@@ -908,8 +934,8 @@ class HWLDFWordAccumulator {
        }
 
        /**
-        * @param $words
-        * @param $tag string
+        * @param string[] $words
+        * @param string $tag
         */
        public function addWords( $words, $tag = '' ) {
                if ( $tag != $this->tag ) {
@@ -931,7 +957,7 @@ class HWLDFWordAccumulator {
        }
 
        /**
-        * @return array
+        * @return string[]
         */
        public function getLines() {
                $this->flushLine( '~done' );
@@ -949,8 +975,8 @@ class WordLevelDiff extends MappedDiff {
        const MAX_LINE_LENGTH = 10000;
 
        /**
-        * @param $orig_lines
-        * @param $closing_lines
+        * @param string[] $orig_lines
+        * @param string[] $closing_lines
         */
        public function __construct( $orig_lines, $closing_lines ) {
                wfProfileIn( __METHOD__ );
@@ -964,8 +990,9 @@ class WordLevelDiff extends MappedDiff {
        }
 
        /**
-        * @param $lines
-        * @return array
+        * @param string[] $lines
+        *
+        * @return array[]
         */
        private function split( $lines ) {
                wfProfileIn( __METHOD__ );
@@ -1005,7 +1032,7 @@ class WordLevelDiff extends MappedDiff {
        }
 
        /**
-        * @return array
+        * @return string[]
         */
        public function orig() {
                wfProfileIn( __METHOD__ );
@@ -1025,7 +1052,7 @@ class WordLevelDiff extends MappedDiff {
        }
 
        /**
-        * @return array
+        * @return string[]
         */
        public function closing() {
                wfProfileIn( __METHOD__ );
@@ -1043,4 +1070,5 @@ class WordLevelDiff extends MappedDiff {
 
                return $lines;
        }
+
 }
index d9e1c95..d8a9ba3 100644 (file)
@@ -34,6 +34,7 @@
  * @ingroup DifferenceEngine
  */
 abstract class DiffFormatter {
+
        /** @var int Number of leading context "lines" to preserve.
         *
         * This should be left at zero for this class, but subclasses
@@ -51,7 +52,8 @@ abstract class DiffFormatter {
        /**
         * Format a diff.
         *
-        * @param $diff Diff A Diff object.
+        * @param Diff $diff A Diff object.
+        *
         * @return string The formatted output.
         */
        public function format( $diff ) {
@@ -124,7 +126,8 @@ abstract class DiffFormatter {
         * @param int $ybeg
         * @param int $ylen
         * @param $edits
-        * @throws MWException
+        *
+        * @throws MWException If the edit type is not known.
         */
        protected function block( $xbeg, $xlen, $ybeg, $ylen, &$edits ) {
                wfProfileIn( __METHOD__ );
@@ -161,10 +164,11 @@ abstract class DiffFormatter {
        }
 
        /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
+        * @param int $xbeg
+        * @param int $xlen
+        * @param int $ybeg
+        * @param int $ylen
+        *
         * @return string
         */
        protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
@@ -178,16 +182,28 @@ abstract class DiffFormatter {
                return $xbeg . ( $xlen ? ( $ylen ? 'c' : 'd' ) : 'a' ) . $ybeg;
        }
 
+       /**
+        * Called at the start of a block of connected edits.
+        * This default implementation writes the header and a newline to the output buffer.
+        *
+        * @param string $header
+        */
        protected function startBlock( $header ) {
                echo $header . "\n";
        }
 
+       /**
+        * Called at the end of a block of connected edits.
+        * This default implementation does nothing.
+        */
        protected function endBlock() {
        }
 
        /**
-        * @param $lines
-        * @param $prefix string
+        * Writes all (optionally prefixed) lines to the output buffer, separated by newlines.
+        *
+        * @param string[] $lines
+        * @param string $prefix
         */
        protected function lines( $lines, $prefix = ' ' ) {
                foreach ( $lines as $line ) {
@@ -196,33 +212,36 @@ abstract class DiffFormatter {
        }
 
        /**
-        * @param $lines
+        * @param string[] $lines
         */
        protected function context( $lines ) {
                $this->lines( $lines );
        }
 
        /**
-        * @param $lines
+        * @param string[] $lines
         */
        protected function added( $lines ) {
                $this->lines( $lines, '>' );
        }
 
        /**
-        * @param $lines
+        * @param string[] $lines
         */
        protected function deleted( $lines ) {
                $this->lines( $lines, '<' );
        }
 
        /**
-        * @param $orig
-        * @param $closing
+        * Writes the two sets of lines to the output buffer, separated by "---" and a newline.
+        *
+        * @param string[] $orig
+        * @param string[] $closing
         */
        protected function changed( $orig, $closing ) {
                $this->deleted( $orig );
                echo "---\n";
                $this->added( $closing );
        }
+
 }
index d6cf694..414b9f8 100644 (file)
@@ -34,6 +34,7 @@ define( 'MW_DIFF_VERSION', '1.11a' );
  * @ingroup DifferenceEngine
  */
 class DifferenceEngine extends ContextSource {
+
        /** @var int */
        public $mOldid;
 
@@ -97,14 +98,14 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * Constructor
-        * @param $context IContextSource context to use, anything else will be ignored
-        * @param $old Integer old ID we want to show and diff with.
-        * @param $new String|int either revision ID or 'prev' or 'next'. Default: 0.
-        * @param $rcid Integer Deprecated, no longer used!
-        * @param $refreshCache boolean If set, refreshes the diff cache
-        * @param $unhide boolean If set, allow viewing deleted revs
+        * @param IContextSource $context context to use, anything else will be ignored
+        * @param int $old old ID we want to show and diff with.
+        * @param string|int $new either revision ID or 'prev' or 'next'. Default: 0.
+        * @param int $rcid Deprecated, no longer used!
+        * @param bool $refreshCache If set, refreshes the diff cache
+        * @param bool $unhide If set, allow viewing deleted revs
         */
-       function __construct( $context = null, $old = 0, $new = 0, $rcid = 0,
+       public function __construct( $context = null, $old = 0, $new = 0, $rcid = 0,
                $refreshCache = false, $unhide = false
        ) {
                if ( $context instanceof IContextSource ) {
@@ -120,16 +121,16 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
-        * @param $value bool
+        * @param bool $value
         */
-       function setReducedLineNumbers( $value = true ) {
+       public function setReducedLineNumbers( $value = true ) {
                $this->mReducedLineNumbers = $value;
        }
 
        /**
         * @return Language
         */
-       function getDiffLang() {
+       public function getDiffLang() {
                if ( $this->mDiffLang === null ) {
                        # Default language in which the diff text is written.
                        $this->mDiffLang = $this->getTitle()->getPageLanguage();
@@ -141,23 +142,23 @@ class DifferenceEngine extends ContextSource {
        /**
         * @return bool
         */
-       function wasCacheHit() {
+       public function wasCacheHit() {
                return $this->mCacheHit;
        }
 
        /**
         * @return int
         */
-       function getOldid() {
+       public function getOldid() {
                $this->loadRevisionIds();
 
                return $this->mOldid;
        }
 
        /**
-        * @return Bool|int
+        * @return bool|int
         */
-       function getNewid() {
+       public function getNewid() {
                $this->loadRevisionIds();
 
                return $this->mNewid;
@@ -167,10 +168,11 @@ class DifferenceEngine extends ContextSource {
         * Look up a special:Undelete link to the given deleted revision id,
         * as a workaround for being unable to load deleted diffs in currently.
         *
-        * @param int $id revision ID
+        * @param int $id Revision ID
+        *
         * @return mixed URL or false
         */
-       function deletedLink( $id ) {
+       public function deletedLink( $id ) {
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $row = $dbr->selectRow( 'archive', '*',
@@ -193,10 +195,11 @@ class DifferenceEngine extends ContextSource {
        /**
         * Build a wikitext link toward a deleted revision, if viewable.
         *
-        * @param int $id revision ID
-        * @return string wikitext fragment
+        * @param int $id Revision ID
+        *
+        * @return string Wikitext fragment
         */
-       function deletedIdMarker( $id ) {
+       public function deletedIdMarker( $id ) {
                $link = $this->deletedLink( $id );
                if ( $link ) {
                        return "[$link $id]";
@@ -225,7 +228,7 @@ class DifferenceEngine extends ContextSource {
                        $this->getLanguage()->listToText( $missing ), count( $missing ) );
        }
 
-       function showDiffPage( $diffOnly = false ) {
+       public function showDiffPage( $diffOnly = false ) {
                wfProfileIn( __METHOD__ );
 
                # Allow frames except in certain special cases
@@ -451,7 +454,7 @@ class DifferenceEngine extends ContextSource {
         * Side effect: When the patrol link is build, this method will call
         * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
         *
-        * @return String
+        * @return string
         */
        protected function markPatrolledLink() {
                global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
@@ -518,8 +521,9 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
-        * @param $rev Revision
-        * @return String
+        * @param Revision $rev
+        *
+        * @return string
         */
        protected function revisionDeleteLink( $rev ) {
                $link = Linker::getRevDeleteLink( $this->getUser(), $rev, $rev->getTitle() );
@@ -533,7 +537,7 @@ class DifferenceEngine extends ContextSource {
        /**
         * Show the new revision of the page.
         */
-       function renderNewRevision() {
+       public function renderNewRevision() {
                wfProfileIn( __METHOD__ );
                $out = $this->getOutput();
                $revHeader = $this->getRevisionHeader( $this->mNewRev );
@@ -616,7 +620,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @return bool
         */
-       function showDiff( $otitle, $ntitle, $notice = '' ) {
+       public function showDiff( $otitle, $ntitle, $notice = '' ) {
                $diff = $this->getDiff( $otitle, $ntitle, $notice );
                if ( $diff === false ) {
                        $this->showMissingRevision();
@@ -633,7 +637,7 @@ class DifferenceEngine extends ContextSource {
        /**
         * Add style sheets and supporting JS for diff display.
         */
-       function showDiffStyle() {
+       public function showDiffStyle() {
                $this->getOutput()->addModuleStyles( 'mediawiki.action.history.diff' );
        }
 
@@ -643,9 +647,10 @@ class DifferenceEngine extends ContextSource {
         * @param string|bool $otitle Header for old text or false
         * @param string|bool $ntitle Header for new text or false
         * @param string $notice HTML between diff header and body
+        *
         * @return mixed
         */
-       function getDiff( $otitle, $ntitle, $notice = '' ) {
+       public function getDiff( $otitle, $ntitle, $notice = '' ) {
                $body = $this->getDiffBody();
                if ( $body === false ) {
                        return false;
@@ -747,9 +752,10 @@ class DifferenceEngine extends ContextSource {
        /**
         * Returns the cache key for diff body text or content.
         *
-        * @return string
         * @since 1.23
+        *
         * @throws MWException
+        * @return string
         */
        protected function getDiffBodyCacheKey() {
                if ( !$this->mOldid || !$this->mNewid ) {
@@ -771,14 +777,15 @@ class DifferenceEngine extends ContextSource {
         * perhaps taking advantage of the content's native form. This is required for all content
         * models that are not text based.
         *
-        * @param $old Content: old content
-        * @param $new Content: new content
+        * @since 1.21
+        *
+        * @param Content $old Old content
+        * @param Content $new New content
         *
+        * @throws MWException If old or new content is not an instance of TextContent.
         * @return bool|string
-        * @since 1.21
-        * @throws MWException if $old or $new are not instances of TextContent.
         */
-       function generateContentDiffBody( Content $old, Content $new ) {
+       public function generateContentDiffBody( Content $old, Content $new ) {
                if ( !( $old instanceof TextContent ) ) {
                        throw new MWException( "Diff not implemented for " . get_class( $old ) . "; " .
                                "override generateContentDiffBody to fix this." );
@@ -798,12 +805,13 @@ class DifferenceEngine extends ContextSource {
        /**
         * Generate a diff, no caching
         *
-        * @param string $otext old text, must be already segmented
-        * @param string $ntext new text, must be already segmented
+        * @param string $otext Old text, must be already segmented
+        * @param string $ntext New text, must be already segmented
+        *
         * @return bool|string
         * @deprecated since 1.21, use generateContentDiffBody() instead!
         */
-       function generateDiffBody( $otext, $ntext ) {
+       public function generateDiffBody( $otext, $ntext ) {
                ContentHandler::deprecated( __METHOD__, "1.21" );
 
                return $this->generateTextDiffBody( $otext, $ntext );
@@ -816,9 +824,10 @@ class DifferenceEngine extends ContextSource {
         *
         * @param string $otext old text, must be already segmented
         * @param string $ntext new text, must be already segmented
+        *
         * @return bool|string
         */
-       function generateTextDiffBody( $otext, $ntext ) {
+       public function generateTextDiffBody( $otext, $ntext ) {
                global $wgExternalDiffEngine, $wgContLang;
 
                wfProfileIn( __METHOD__ );
@@ -897,7 +906,7 @@ class DifferenceEngine extends ContextSource {
         * Generate a debug comment indicating diff generating time,
         * server node, and generator backend.
         *
-        * @param String $generator : What diff engine was used
+        * @param string $generator : What diff engine was used
         *
         * @return string
         */
@@ -920,11 +929,11 @@ class DifferenceEngine extends ContextSource {
        /**
         * Replace line numbers with the text in the user's language
         *
-        * @param String $text
+        * @param string $text
         *
         * @return mixed
         */
-       function localiseLineNumbers( $text ) {
+       public function localiseLineNumbers( $text ) {
                return preg_replace_callback(
                        '/<!--LINE (\d+)-->/',
                        array( &$this, 'localiseLineNumbersCb' ),
@@ -932,7 +941,7 @@ class DifferenceEngine extends ContextSource {
                );
        }
 
-       function localiseLineNumbersCb( $matches ) {
+       public function localiseLineNumbersCb( $matches ) {
                if ( $matches[1] === '1' && $this->mReducedLineNumbers ) {
                        return '';
                }
@@ -942,9 +951,10 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * If there are revisions between the ones being compared, return a note saying so.
+        *
         * @return string
         */
-       function getMultiNotice() {
+       public function getMultiNotice() {
                if ( !is_object( $this->mOldRev ) || !is_object( $this->mNewRev ) ) {
                        return '';
                } elseif ( !$this->mOldPage->equals( $this->mNewPage ) ) {
@@ -978,9 +988,11 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * Get a notice about how many intermediate edits and users there are
-        * @param $numEdits int
-        * @param $numUsers int
-        * @param $limit int
+        *
+        * @param int $numEdits
+        * @param int $numUsers
+        * @param int $limit
+        *
         * @return string
         */
        public static function intermediateEditsMsg( $numEdits, $numUsers, $limit ) {
@@ -999,10 +1011,11 @@ class DifferenceEngine extends ContextSource {
        /**
         * Get a header for a specified revision.
         *
-        * @param $rev Revision
+        * @param Revision $rev
         * @param string $complete 'complete' to get the header wrapped depending
         *        the visibility of the revision and a link to edit the page.
-        * @return String HTML fragment
+        *
+        * @return string HTML fragment
         */
        protected function getRevisionHeader( Revision $rev, $complete = '' ) {
                $lang = $this->getLanguage();
@@ -1064,7 +1077,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @return string
         */
-       function addHeader( $diff, $otitle, $ntitle, $multi = '', $notice = '' ) {
+       public function addHeader( $diff, $otitle, $ntitle, $multi = '', $notice = '' ) {
                // shared.css sets diff in interface language/dir, but the actual content
                // is often in a different language, mostly the page content language/dir
                $tableClass = 'diff diff-contentalign-' . htmlspecialchars( $this->getDiffLang()->alignStart() );
@@ -1113,7 +1126,7 @@ class DifferenceEngine extends ContextSource {
         * Use specified text instead of loading from the database
         * @deprecated since 1.21, use setContent() instead.
         */
-       function setText( $oldText, $newText ) {
+       public function setText( $oldText, $newText ) {
                ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() );
@@ -1126,7 +1139,7 @@ class DifferenceEngine extends ContextSource {
         * Use specified text instead of loading from the database
         * @since 1.21
         */
-       function setContent( Content $oldContent, Content $newContent ) {
+       public function setContent( Content $oldContent, Content $newContent ) {
                $this->mOldContent = $oldContent;
                $this->mNewContent = $newContent;
 
@@ -1139,7 +1152,7 @@ class DifferenceEngine extends ContextSource {
         * (Defaults to page content language).
         * @since 1.19
         */
-       function setTextLanguage( $lang ) {
+       public function setTextLanguage( $lang ) {
                $this->mDiffLang = wfGetLangObj( $lang );
        }
 
@@ -1149,7 +1162,8 @@ class DifferenceEngine extends ContextSource {
         *
         * @param int $old Revision id, e.g. from URL parameter 'oldid'
         * @param int|string $new Revision id or strings 'next' or 'prev', e.g. from URL parameter 'diff'
-        * @return array Array of two revision ids, older first, later second.
+        *
+        * @return int[] List of two revision ids, older first, later second.
         *     Zero signifies invalid argument passed.
         *     false signifies that there is no previous/next revision ($old is the oldest/newest one).
         */
@@ -1208,7 +1222,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @return bool
         */
-       function loadRevisionData() {
+       public function loadRevisionData() {
                if ( $this->mRevisionsLoaded ) {
                        return true;
                }
@@ -1288,7 +1302,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @return bool
         */
-       function loadText() {
+       public function loadText() {
                if ( $this->mTextLoaded == 2 ) {
                        return true;
                }
@@ -1322,7 +1336,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @return bool
         */
-       function loadNewText() {
+       public function loadNewText() {
                if ( $this->mTextLoaded >= 1 ) {
                        return true;
                }
@@ -1337,4 +1351,5 @@ class DifferenceEngine extends ContextSource {
 
                return true;
        }
+
 }
index 5f28627..ac8f758 100644 (file)
@@ -31,6 +31,7 @@
  * @ingroup DifferenceEngine
  */
 class TableDiffFormatter extends DiffFormatter {
+
        function __construct() {
                $this->leadingContextLines = 2;
                $this->trailingContextLines = 2;
@@ -38,7 +39,8 @@ class TableDiffFormatter extends DiffFormatter {
 
        /**
         * @static
-        * @param $msg
+        * @param string $msg
+        *
         * @return mixed
         */
        public static function escapeWhiteSpace( $msg ) {
@@ -50,10 +52,11 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
+        * @param int $xbeg
+        * @param int $xlen
+        * @param int $ybeg
+        * @param int $ylen
+        *
         * @return string
         */
        protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
@@ -64,7 +67,9 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $header
+        * Writes the header to the output buffer.
+        *
+        * @param string $header
         */
        protected function startBlock( $header ) {
                echo $header;
@@ -73,12 +78,19 @@ class TableDiffFormatter extends DiffFormatter {
        protected function endBlock() {
        }
 
+       /**
+        * @param string[] $lines
+        * @param string $prefix
+        * @param string $color
+        */
        protected function lines( $lines, $prefix = ' ', $color = 'white' ) {
        }
 
        /**
         * HTML-escape parameter before calling this
-        * @param $line
+        *
+        * @param string $line
+        *
         * @return string
         */
        protected function addedLine( $line ) {
@@ -87,7 +99,9 @@ class TableDiffFormatter extends DiffFormatter {
 
        /**
         * HTML-escape parameter before calling this
-        * @param $line
+        *
+        * @param string $line
+        *
         * @return string
         */
        protected function deletedLine( $line ) {
@@ -96,7 +110,9 @@ class TableDiffFormatter extends DiffFormatter {
 
        /**
         * HTML-escape parameter before calling this
-        * @param $line
+        *
+        * @param string $line
+        *
         * @return string
         */
        protected function contextLine( $line ) {
@@ -104,9 +120,10 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $marker
-        * @param $class
-        * @param $line
+        * @param string $marker
+        * @param string $class Unused
+        * @param string $line
+        *
         * @return string
         */
        protected function wrapLine( $marker, $class, $line ) {
@@ -126,7 +143,9 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $lines array
+        * Writes all lines to the output buffer, each enclosed in <tr>.
+        *
+        * @param string[] $lines
         */
        protected function added( $lines ) {
                foreach ( $lines as $line ) {
@@ -137,7 +156,9 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $lines
+        * Writes all lines to the output buffer, each enclosed in <tr>.
+        *
+        * @param string[] $lines
         */
        protected function deleted( $lines ) {
                foreach ( $lines as $line ) {
@@ -148,7 +169,9 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $lines
+        * Writes all lines to the output buffer, each enclosed in <tr>.
+        *
+        * @param string[] $lines
         */
        protected function context( $lines ) {
                foreach ( $lines as $line ) {
@@ -159,8 +182,10 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $orig
-        * @param $closing
+        * Writes the two sets of lines to the output buffer, each enclosed in <tr>.
+        *
+        * @param string[] $orig
+        * @param string[] $closing
         */
        protected function changed( $orig, $closing ) {
                wfProfileIn( __METHOD__ );
@@ -183,4 +208,5 @@ class TableDiffFormatter extends DiffFormatter {
                }
                wfProfileOut( __METHOD__ );
        }
+
 }
index 0a86ccc..32a7605 100644 (file)
@@ -29,6 +29,7 @@
  * @ingroup DifferenceEngine
  */
 class UnifiedDiffFormatter extends DiffFormatter {
+
        /** @var int */
        protected $leadingContextLines = 2;
 
@@ -36,22 +37,22 @@ class UnifiedDiffFormatter extends DiffFormatter {
        protected $trailingContextLines = 2;
 
        /**
-        * @param $lines
+        * @param string[] $lines
         */
        protected function added( $lines ) {
                $this->lines( $lines, '+' );
        }
 
        /**
-        * @param $lines
+        * @param string[] $lines
         */
        protected function deleted( $lines ) {
                $this->lines( $lines, '-' );
        }
 
        /**
-        * @param $orig
-        * @param $closing
+        * @param string[] $orig
+        * @param string[] $closing
         */
        protected function changed( $orig, $closing ) {
                $this->deleted( $orig );
@@ -59,13 +60,15 @@ class UnifiedDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @param $xbeg
-        * @param $xlen
-        * @param $ybeg
-        * @param $ylen
+        * @param int $xbeg
+        * @param int $xlen
+        * @param int $ybeg
+        * @param int $ylen
+        *
         * @return string
         */
        protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
                return "@@ -$xbeg,$xlen +$ybeg,$ylen @@";
        }
+
 }
index 7c019b0..7a0f740 100644 (file)
@@ -580,6 +580,7 @@ class WikiDiff3 {
 
                return $this->length;
        }
+
 }
 
 /**
@@ -589,6 +590,7 @@ class WikiDiff3 {
  * @ingroup DifferenceEngine
  */
 class RangeDifference {
+
        /** @var int */
        public $leftstart;
 
@@ -615,4 +617,5 @@ class RangeDifference {
                $this->rightend = $rightend;
                $this->rightlength = $rightend - $rightstart;
        }
+
 }
index 2944c24..3cf3188 100644 (file)
@@ -28,6 +28,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
        }
 
        function getInputHTML( $value ) {
+               $value = HTMLFormField::forceToStringRecursive( $value );
                $html = $this->formatOptions( $this->getOptions(), $value );
 
                return $html;
@@ -103,11 +104,12 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
        }
 
        function filterDataForSubmit( $data ) {
+               $data = HTMLFormField::forceToStringRecursive( $data );
                $options = HTMLFormField::flattenOptions( $this->getOptions() );
 
                $res = array();
                foreach ( $options as $opt ) {
-                       $res["$opt"] = in_array( $opt, $data );
+                       $res["$opt"] = in_array( $opt, $data, true );
                }
 
                return $res;
index aa0ea5d..c52f0a8 100644 (file)
@@ -17,7 +17,7 @@ class HTMLRadioField extends HTMLFormField {
 
                $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
 
-               if ( in_array( $value, $validOptions ) ) {
+               if ( in_array( strval( $value ), $validOptions, true ) ) {
                        return true;
                } else {
                        return $this->msg( 'htmlform-select-badoption' )->parse();
@@ -33,7 +33,7 @@ class HTMLRadioField extends HTMLFormField {
         * @return String
         */
        function getInputHTML( $value ) {
-               $html = $this->formatOptions( $this->getOptions(), $value );
+               $html = $this->formatOptions( $this->getOptions(), strval( $value ) );
 
                return $html;
        }
@@ -51,7 +51,7 @@ class HTMLRadioField extends HTMLFormField {
                                $html .= $this->formatOptions( $info, $value );
                        } else {
                                $id = Sanitizer::escapeId( $this->mID . "-$info" );
-                               $radio = Xml::radio( $this->mName, $info, $info == $value, $attribs + array( 'id' => $id ) );
+                               $radio = Xml::radio( $this->mName, $info, $info === $value, $attribs + array( 'id' => $id ) );
                                $radio .= '&#160;' . call_user_func( $elementFunc, 'label', array( 'for' => $id ), $label );
 
                                $html .= ' ' . Html::rawElement(
index 2e91a23..564927f 100644 (file)
@@ -72,7 +72,7 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
 
                        if ( $list == 'other' ) {
                                $final = $text;
-                       } elseif ( !in_array( $list, $this->mFlatOptions ) ) {
+                       } elseif ( !in_array( $list, $this->mFlatOptions, true ) ) {
                                # User has spoofed the select form to give an option which wasn't
                                # in the original offer.  Sulk...
                                $final = $text;
index 0437480..c32b445 100644 (file)
@@ -13,7 +13,7 @@ class HTMLSelectField extends HTMLFormField {
 
                $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
 
-               if ( in_array( $value, $validOptions ) ) {
+               if ( in_array( strval( $value ), $validOptions, true ) ) {
                        return true;
                } else {
                        return $this->msg( 'htmlform-select-badoption' )->parse();
index 045b8df..e8bcb5b 100644 (file)
@@ -21,7 +21,10 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                $valInSelect = false;
 
                if ( $value !== false ) {
-                       $valInSelect = in_array( $value, HTMLFormField::flattenOptions( $this->getOptions() ) );
+                       $value = strval( $value );
+                       $valInSelect = in_array(
+                               $value, HTMLFormField::flattenOptions( $this->getOptions() ), true
+                       );
                }
 
                $selected = $valInSelect ? $value : 'other';
@@ -67,7 +70,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                if ( $request->getCheck( $this->mName ) ) {
                        $val = $request->getText( $this->mName );
 
-                       if ( $val == 'other' ) {
+                       if ( $val === 'other' ) {
                                $val = $request->getText( $this->mName . '-other' );
                        }
 
index 24bc456..592a1ca 100644 (file)
@@ -358,9 +358,9 @@ In <strong>UTF-8 mode</strong>, MySQL will know what character set your data is
 
        'config-mssql-auth'               => 'Authentication type:',
        'config-mssql-install-auth'       => 'Select the authentication type that will be used to connect to the database during the installation process.
-If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
+If you select "{{int:config-mssql-windowsauth}}", the credentials of whatever user the webserver is running as will be used.',
        'config-mssql-web-auth'           => 'Select the authentication type that the web server will use to connect to the database server, during ordinary operation of the wiki.
-If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
+If you select "{{int:config-mssql-windowsauth}}", the credentials of whatever user the webserver is running as will be used.',
        'config-mssql-sqlauth'            => 'SQL Server Authentication',
        'config-mssql-windowsauth'        => 'Windows Authentication',
        'config-site-name'                => 'Name of wiki:',
index f83db54..4bc6cad 100644 (file)
@@ -482,7 +482,7 @@ class WebInstaller_DBConnect extends WebInstallerPage {
                $defaultType = $this->getVar( 'wgDBtype' );
 
                // Messages: config-dbsupport-mysql, config-dbsupport-postgres, config-dbsupport-oracle,
-               // config-dbsupport-sqlite
+               // config-dbsupport-sqlite, config-dbsupport-mssql
                $dbSupport = '';
                foreach ( Installer::getDBTypes() as $type ) {
                        $dbSupport .= wfMessage( "config-dbsupport-$type" )->plain() . "\n";
index 3b79684..e490e4f 100644 (file)
@@ -61,21 +61,27 @@ class CSSMin {
        /**
         * Gets a list of local file paths which are referenced in a CSS style sheet
         *
+        * This function will always return an empty array if the second parameter is not given or null
+        * for backwards-compatibility.
+        *
         * @param string $source CSS data to remap
         * @param string $path File path where the source was read from (optional)
         * @return array List of local file references
         */
        public static function getLocalFileReferences( $source, $path = null ) {
+               if ( $path === null ) {
+                       return array();
+               }
+
+               $path = rtrim( $path, '/' ) . '/';
                $files = array();
+
                $rFlags = PREG_OFFSET_CAPTURE | PREG_SET_ORDER;
                if ( preg_match_all( '/' . self::URL_REGEX . '/', $source, $matches, $rFlags ) ) {
                        foreach ( $matches as $match ) {
-                               $file = ( isset( $path )
-                                       ? rtrim( $path, '/' ) . '/'
-                                       : '' ) . "{$match['file'][0]}";
-
+                               $file = $path . $match['file'][0];
                                // Only proceed if we can access the file
-                               if ( !is_null( $path ) && file_exists( $file ) ) {
+                               if ( file_exists( $file ) ) {
                                        $files[] = $file;
                                }
                        }
index 3dce961..57d45ed 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * lessphp v0.4.0@261f1bd28f
+ * lessphp v0.4.0@b7cd5c79e8
  * http://leafo.net/lessphp
  *
  * LESS CSS compiler, adapted from http://lesscss.org
@@ -1011,6 +1011,39 @@ class lessc {
                return $this->lib_rgbahex($color);
        }
 
+       /**
+        * Given an url, decide whether to output a regular link or the base64-encoded contents of the file
+        *
+        * @param  array  $value either an argument list (two strings) or a single string
+        * @return string        formatted url(), either as a link or base64-encoded
+        */
+       protected function lib_data_uri($value) {
+               $mime = ($value[0] === 'list') ? $value[2][0][2] : null;
+               $url = ($value[0] === 'list') ? $value[2][1][2][0] : $value[2][0];
+
+               $fullpath = $this->findImport($url);
+
+               if($fullpath && ($fsize = filesize($fullpath)) !== false) {
+                       // IE8 can't handle data uris larger than 32KB
+                       if($fsize/1024 < 32) {
+                               if(is_null($mime)) {
+                                       if(class_exists('finfo')) { // php 5.3+
+                                               $finfo = new finfo(FILEINFO_MIME);
+                                               $mime = explode('; ', $finfo->file($fullpath));
+                                               $mime = $mime[0];
+                                       } elseif(function_exists('mime_content_type')) { // PHP 5.2
+                                               $mime = mime_content_type($fullpath);
+                                       }
+                               }
+
+                               if(!is_null($mime)) // fallback if the mime type is still unknown
+                                       $url = sprintf('data:%s;base64,%s', $mime, base64_encode(file_get_contents($fullpath)));
+                       }
+               }
+
+               return 'url("'.$url.'")';
+       }
+
        // utility func to unquote a string
        protected function lib_e($arg) {
                switch ($arg[0]) {
@@ -1234,24 +1267,44 @@ class lessc {
        }
 
        protected function lib_contrast($args) {
-               if ($args[0] != 'list' || count($args[2]) < 3) {
-                       return array(array('color', 0, 0, 0), 0);
-               }
+           $darkColor  = array('color', 0, 0, 0);
+           $lightColor = array('color', 255, 255, 255);
+           $threshold  = 0.43;
 
-               list($inputColor, $darkColor, $lightColor) = $args[2];
+           if ( $args[0] == 'list' ) {
+               $inputColor = ( isset($args[2][0]) ) ? $this->assertColor($args[2][0])  : $lightColor;
+               $darkColor  = ( isset($args[2][1]) ) ? $this->assertColor($args[2][1])  : $darkColor;
+               $lightColor = ( isset($args[2][2]) ) ? $this->assertColor($args[2][2])  : $lightColor;
+               $threshold  = ( isset($args[2][3]) ) ? $this->assertNumber($args[2][3]) : $threshold;
+           }
+           else {
+               $inputColor  = $this->assertColor($args);
+           }
 
-               $inputColor = $this->assertColor($inputColor);
-               $darkColor = $this->assertColor($darkColor);
-               $lightColor = $this->assertColor($lightColor);
-               $hsl = $this->toHSL($inputColor);
+           $inputColor = $this->coerceColor($inputColor);
+           $darkColor  = $this->coerceColor($darkColor);
+           $lightColor = $this->coerceColor($lightColor);
 
-               if ($hsl[3] > 50) {
-                       return $darkColor;
-               }
+           //Figure out which is actually light and dark!
+           if ( $this->lib_luma($darkColor) > $this->lib_luma($lightColor) ) {
+               $t  = $lightColor;
+               $lightColor = $darkColor;
+               $darkColor  = $t;
+           }
 
-               return $lightColor;
+           $inputColor_alpha = $this->lib_alpha($inputColor);
+           if ( ( $this->lib_luma($inputColor) * $inputColor_alpha) < $threshold) {
+               return $lightColor;
+           }
+           return $darkColor;
        }
 
+       protected function lib_luma($color) {
+           $color = $this->coerceColor($color);
+           return (0.2126 * $color[0] / 255) + (0.7152 * $color[1] / 255) + (0.0722 * $color[2] / 255);
+       }
+
+
        public function assertColor($value, $error = "expected color value") {
                $color = $this->coerceColor($value);
                if (is_null($color)) $this->throwError($error);
@@ -1475,8 +1528,9 @@ class lessc {
 
                        list(, $name, $args) = $value;
                        if ($name == "%") $name = "_sprintf";
+
                        $f = isset($this->libFunctions[$name]) ?
-                               $this->libFunctions[$name] : array($this, 'lib_'.$name);
+                               $this->libFunctions[$name] : array($this, 'lib_'.str_replace('-', '_', $name));
 
                        if (is_callable($f)) {
                                if ($args[0] == 'list')
@@ -2338,7 +2392,7 @@ class lessc_parser {
                        $this->throwError();
 
                // TODO report where the block was opened
-               if (!is_null($this->env->parent))
+               if ( !property_exists($this->env, 'parent') || !is_null($this->env->parent) )
                        throw new exception('parse error: unclosed block');
 
                return $this->env;
index 857943e..f6fe243 100644 (file)
@@ -250,8 +250,10 @@ abstract class BagOStuff {
         * @param $value mixed
         * @param $exptime int
         * @return bool success
+        * @deprecated 1.23
         */
        public function replace( $key, $value, $exptime = 0 ) {
+               wfDeprecated( __METHOD__, '1.23' );
                if ( $this->get( $key ) !== false ) {
                        return $this->set( $key, $value, $exptime );
                }
index f1644ed..87acb53 100644 (file)
@@ -107,17 +107,6 @@ class MemcachedBagOStuff extends BagOStuff {
                        $this->fixExpiry( $exptime ) );
        }
 
-       /**
-        * @param $key string
-        * @param $value int
-        * @param $exptime
-        * @return Mixed
-        */
-       public function replace( $key, $value, $exptime = 0 ) {
-               return $this->client->replace( $this->encodeKey( $key ), $value,
-                       $this->fixExpiry( $exptime ) );
-       }
-
        /**
         * Get the underlying client object. This is provided for debugging
         * purposes.
index 0c3b228..18546d4 100644 (file)
@@ -176,17 +176,6 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                return $this->checkResult( $key, parent::add( $key, $value, $exptime ) );
        }
 
-       /**
-        * @param $key string
-        * @param $value int
-        * @param $exptime
-        * @return Mixed
-        */
-       public function replace( $key, $value, $exptime = 0 ) {
-               $this->debugLog( "replace($key)" );
-               return $this->checkResult( $key, parent::replace( $key, $value, $exptime ) );
-       }
-
        /**
         * @param $key string
         * @param $value int
index 427143c..f54726f 100644 (file)
@@ -236,37 +236,6 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       /**
-        * Non-atomic implementation of replace(). Could perhaps be done atomically
-        * with WATCH or scripting, but this function is rarely used.
-        */
-       public function replace( $key, $value, $expiry = 0 ) {
-               $section = new ProfileSection( __METHOD__ );
-
-               list( $server, $conn ) = $this->getConnection( $key );
-               if ( !$conn ) {
-                       return false;
-               }
-               if ( !$conn->exists( $key ) ) {
-                       return false;
-               }
-
-               $expiry = $this->convertToRelative( $expiry );
-               try {
-                       if ( !$expiry ) {
-                               $result = $conn->set( $key, $this->serialize( $value ) );
-                       } else {
-                               $result = $conn->setex( $key, $expiry, $this->serialize( $value ) );
-                       }
-               } catch ( RedisException $e ) {
-                       $result = false;
-                       $this->handleException( $conn, $e );
-               }
-
-               $this->logRequest( 'replace', $key, $server, $result );
-               return $result;
-       }
-
        /**
         * Non-atomic implementation of incr().
         *
index 557c1f6..12c452a 100644 (file)
 /**
  * Dynamic JavaScript and CSS resource loading system.
  *
- * Most of the documention is on the MediaWiki documentation wiki starting at:
- *    http://www.mediawiki.org/wiki/ResourceLoader
+ * Most of the documentation is on the MediaWiki documentation wiki starting at:
+ *    https://www.mediawiki.org/wiki/ResourceLoader
  */
 class ResourceLoader {
 
-       /* Protected Static Members */
+       /**
+        * @var int
+        */
        protected static $filterCacheVersion = 7;
+       /**
+        * @var array
+        */
        protected static $requiredSourceProperties = array( 'loadScript' );
 
-       /** Array: List of module name/ResourceLoaderModule object pairs */
+       /**
+        * @var array Module name/ResourceLoaderModule object pairs
+        */
        protected $modules = array();
 
-       /** Associative array mapping module name to info associative array */
+       /**
+        * @var array Associative array mapping module name to info associative array
+        */
        protected $moduleInfos = array();
 
-       /** Associative array mapping framework ids to a list of names of test suite modules */
-       /** like array( 'qunit' => array( 'mediawiki.tests.qunit.suites', 'ext.foo.tests', .. ), .. ) */
+       /**
+        * @var array Associative array mapping framework ids to a list of names of test suite modules
+        *      like array( 'qunit' => array( 'mediawiki.tests.qunit.suites', 'ext.foo.tests', .. ), .. )
+        */
        protected $testModuleNames = array();
 
-       /** array( 'source-id' => array( 'loadScript' => 'http://.../load.php' ) ) **/
+       /**
+        * @var array e.g. array( 'source-id' => array( 'loadScript' => 'http://.../load.php' ) )
+        */
        protected $sources = array();
 
-       /** @var bool */
+       /**
+        * @var bool
+        */
        protected $hasErrors = false;
 
-       /* Protected Methods */
-
        /**
-        * Loads information stored in the database about modules.
+        * Load information stored in the database about modules.
         *
         * This method grabs modules dependencies from the database and updates modules
         * objects.
@@ -64,7 +77,7 @@ class ResourceLoader {
         * performance improvement.
         *
         * @param array $modules List of module names to preload information for
-        * @param $context ResourceLoaderContext: Context to load the information within
+        * @param ResourceLoaderContext $context Context to load the information within
         */
        public function preloadModuleInfo( array $modules, ResourceLoaderContext $context ) {
                if ( !count( $modules ) ) {
@@ -122,18 +135,19 @@ class ResourceLoader {
        }
 
        /**
-        * Runs JavaScript or CSS data through a filter, caching the filtered result for future calls.
+        * Run JavaScript or CSS data through a filter, caching the filtered result for future calls.
         *
         * Available filters are:
-        *  - minify-js \see JavaScriptMinifier::minify
-        *  - minify-css \see CSSMin::minify
+        *
+        *    - minify-js \see JavaScriptMinifier::minify
+        *    - minify-css \see CSSMin::minify
         *
         * If $data is empty, only contains whitespace or the filter was unknown,
         * $data is returned unmodified.
         *
         * @param string $filter Name of filter to run
         * @param string $data Text to filter, such as JavaScript or CSS text
-        * @return String: Filtered data, or a comment containing an error message
+        * @return string Filtered data, or a comment containing an error message
         */
        protected function filter( $filter, $data ) {
                global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength;
@@ -193,7 +207,7 @@ class ResourceLoader {
        /* Methods */
 
        /**
-        * Registers core modules and runs registration hooks.
+        * Register core modules and runs registration hooks.
         */
        public function __construct() {
                global $IP, $wgResourceModules, $wgResourceLoaderSources, $wgLoadScript, $wgEnableJavaScriptTest;
@@ -220,17 +234,17 @@ class ResourceLoader {
        }
 
        /**
-        * Registers a module with the ResourceLoader system.
+        * Register a module with the ResourceLoader system.
         *
-        * @param $name Mixed: Name of module as a string or List of name/object pairs as an array
+        * @param mixed $name Name of module as a string or List of name/object pairs as an array
         * @param array $info Module info array. For backwards compatibility with 1.17alpha,
         *   this may also be a ResourceLoaderModule object. Optional when using
         *   multiple-registration calling style.
         * @throws MWException: If a duplicate module registration is attempted
         * @throws MWException: If a module name contains illegal characters (pipes or commas)
         * @throws MWException: If something other than a ResourceLoaderModule is being registered
-        * @return Boolean: False if there were any errors, in which case one or more modules were not
-        *     registered
+        * @return boolean False if there were any errors, in which case one or more modules were
+        *   not registered
         */
        public function register( $name, $info = null ) {
                wfProfileIn( __METHOD__ );
@@ -322,8 +336,8 @@ class ResourceLoader {
         * Source properties:
         * 'loadScript': URL (either fully-qualified or protocol-relative) of load.php for this source
         *
-        * @param $id Mixed: source ID (string), or array( id1 => props1, id2 => props2, ... )
-        * @param array $properties source properties
+        * @param mixed $id Source ID (string), or array( id1 => props1, id2 => props2, ... )
+        * @param array $properties Source properties
         * @throws MWException
         */
        public function addSource( $id, $properties = null ) {
@@ -354,9 +368,9 @@ class ResourceLoader {
        }
 
        /**
-        * Get a list of module names
+        * Get a list of module names.
         *
-        * @return Array: List of module names
+        * @return array List of module names
         */
        public function getModuleNames() {
                return array_keys( $this->moduleInfos );
@@ -364,11 +378,12 @@ class ResourceLoader {
 
        /**
         * Get a list of test module names for one (or all) frameworks.
+        *
         * If the given framework id is unknkown, or if the in-object variable is not an array,
         * then it will return an empty array.
         *
-        * @param string $framework Optional. Get only the test module names for one
-        * particular framework.
+        * @param string $framework Get only the test module names for one
+        *   particular framework (optional)
         * @return Array
         */
        public function getTestModuleNames( $framework = 'all' ) {
@@ -416,18 +431,18 @@ class ResourceLoader {
        }
 
        /**
-        * Get the list of sources
+        * Get the list of sources.
         *
-        * @return Array: array( id => array of properties, .. )
+        * @return array Like array( id => array of properties, .. )
         */
        public function getSources() {
                return $this->sources;
        }
 
        /**
-        * Outputs a response to a resource load-request, including a content-type header.
+        * Output a response to a load request, including the content-type header.
         *
-        * @param $context ResourceLoaderContext: Context in which a response should be formed
+        * @param ResourceLoaderContext $context Context in which a response should be formed
         */
        public function respond( ResourceLoaderContext $context ) {
                global $wgCacheEpoch, $wgUseFileCache;
@@ -551,7 +566,7 @@ class ResourceLoader {
 
        /**
         * Send content type and last modified headers to the client.
-        * @param $context ResourceLoaderContext
+        * @param ResourceLoaderContext $context
         * @param string $mtime TS_MW timestamp to use for last-modified
         * @param bool $errors Whether there are commented-out errors in the response
         * @return void
@@ -589,8 +604,11 @@ class ResourceLoader {
        }
 
        /**
+        * Respond with 304 Last Modified if appropiate.
+        *
         * If there's an If-Modified-Since header, respond with a 304 appropriately
         * and clear out the output buffer. If the client cache is too old then do nothing.
+        *
         * @param $context ResourceLoaderContext
         * @param string $mtime The TS_MW timestamp to check the header against
         * @return bool True if 304 header sent and output handled
@@ -624,10 +642,10 @@ class ResourceLoader {
        }
 
        /**
-        * Send out code for a response from file cache if possible
+        * Send out code for a response from file cache if possible.
         *
-        * @param $fileCache ResourceFileCache: Cache object for this request URL
-        * @param $context ResourceLoaderContext: Context in which to generate a response
+        * @param ResourceFileCache $fileCache Cache object for this request URL
+        * @param ResourceLoaderContext $context Context in which to generate a response
         * @return bool If this found a cache file and handled the response
         */
        protected function tryRespondFromFileCache(
@@ -675,10 +693,11 @@ class ResourceLoader {
        }
 
        /**
-        * Generate a CSS or JS comment block. Only use this for public data,
-        * not error message details.
+        * Generate a CSS or JS comment block.
+        *
+        * Only use this for public data, not error message details.
         *
-        * @param $text string
+        * @param string $text
         * @return string
         */
        public static function makeComment( $text ) {
@@ -687,7 +706,7 @@ class ResourceLoader {
        }
 
        /**
-        * Handle exception display
+        * Handle exception display.
         *
         * @param Exception $e to be shown to the user
         * @return string sanitized text that can be returned to the user
@@ -703,7 +722,7 @@ class ResourceLoader {
        }
 
        /**
-        * Generates code for a response
+        * Generate code for a response.
         *
         * @param $context ResourceLoaderContext Context in which to generate a response
         * @param array $modules List of module objects keyed by module name
@@ -887,17 +906,15 @@ class ResourceLoader {
        /* Static Methods */
 
        /**
-        * Returns JS code to call to mw.loader.implement for a module with
-        * given properties.
+        * Return JS code that calls mw.loader.implement with given module properties.
         *
         * @param string $name Module name
-        * @param $scripts Mixed: List of URLs to JavaScript files or String of JavaScript code
-        * @param $styles Mixed: Array of CSS strings keyed by media type, or an array of lists of URLs to
-        * CSS files keyed by media type
-        * @param $messages Mixed: List of messages associated with this module. May either be an
-        *     associative array mapping message key to value, or a JSON-encoded message blob containing
-        *     the same data, wrapped in an XmlJsCode object.
-        *
+        * @param mixed $scripts List of URLs to JavaScript files or String of JavaScript code
+        * @param mixed $styles Array of CSS strings keyed by media type, or an array of lists of URLs
+        *   to CSS files keyed by media type
+        * @param mixed $messages List of messages associated with this module. May either be an
+        *   associative array mapping message key to value, or a JSON-encoded message blob containing
+        *   the same data, wrapped in an XmlJsCode object.
         * @throws MWException
         * @return string
         */
@@ -927,22 +944,24 @@ class ResourceLoader {
        /**
         * Returns JS code which, when called, will register a given list of messages.
         *
-        * @param $messages Mixed: Either an associative array mapping message key to value, or a
-        *     JSON-encoded message blob containing the same data, wrapped in an XmlJsCode object.
-        *
+        * @param mixed $messages Either an associative array mapping message key to value, or a
+        *   JSON-encoded message blob containing the same data, wrapped in an XmlJsCode object.
         * @return string
         */
        public static function makeMessageSetScript( $messages ) {
-               return Xml::encodeJsCall( 'mw.messages.set', array( (object)$messages ) );
+               return Xml::encodeJsCall(
+                       'mw.messages.set',
+                       array( (object)$messages ),
+                       ResourceLoader::inDebugMode()
+               );
        }
 
        /**
         * Combines an associative array mapping media type to CSS into a
         * single stylesheet with "@media" blocks.
         *
-        * @param array $stylePairs Array keyed by media type containing (arrays of) CSS strings.
-        *
-        * @return Array
+        * @param array $stylePairs Array keyed by media type containing (arrays of) CSS strings
+        * @return array
         */
        private static function makeCombinedStyles( array $stylePairs ) {
                $out = array();
@@ -981,16 +1000,23 @@ class ResourceLoader {
         *    - ResourceLoader::makeLoaderStateScript( array( $name => $state, ... ) ):
         *         Set the state of modules with the given names to the given states
         *
-        * @param $name string
+        * @param string $name
         * @param $state
-        *
         * @return string
         */
        public static function makeLoaderStateScript( $name, $state = null ) {
                if ( is_array( $name ) ) {
-                       return Xml::encodeJsCall( 'mw.loader.state', array( $name ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.state',
+                               array( $name ),
+                               ResourceLoader::inDebugMode()
+                       );
                } else {
-                       return Xml::encodeJsCall( 'mw.loader.state', array( $name, $state ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.state',
+                               array( $name, $state ),
+                               ResourceLoader::inDebugMode()
+                       );
                }
        }
 
@@ -1001,19 +1027,20 @@ class ResourceLoader {
         * and $group as supplied.
         *
         * @param string $name Module name
-        * @param $version Integer: Module version number as a timestamp
+        * @param int $version Module version number as a timestamp
         * @param array $dependencies List of module names on which this module depends
         * @param string $group Group which the module is in.
         * @param string $source Source of the module, or 'local' if not foreign.
         * @param string $script JavaScript code
-        *
         * @return string
         */
        public static function makeCustomLoaderScript( $name, $version, $dependencies, $group, $source, $script ) {
                $script = str_replace( "\n", "\n\t", trim( $script ) );
                return Xml::encodeJsCall(
                        "( function ( name, version, dependencies, group, source ) {\n\t$script\n} )",
-                       array( $name, $version, $dependencies, $group, $source ) );
+                       array( $name, $version, $dependencies, $group, $source ),
+                       ResourceLoader::inDebugMode()
+               );
        }
 
        /**
@@ -1034,22 +1061,28 @@ class ResourceLoader {
         *        Registers modules with the given names and parameters.
         *
         * @param string $name Module name
-        * @param $version Integer: Module version number as a timestamp
+        * @param int $version Module version number as a timestamp
         * @param array $dependencies List of module names on which this module depends
-        * @param string $group group which the module is in.
-        * @param string $source source of the module, or 'local' if not foreign
-        *
+        * @param string $group Group which the module is in
+        * @param string $source Source of the module, or 'local' if not foreign
         * @return string
         */
        public static function makeLoaderRegisterScript( $name, $version = null,
                $dependencies = null, $group = null, $source = null
        ) {
                if ( is_array( $name ) ) {
-                       return Xml::encodeJsCall( 'mw.loader.register', array( $name ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.register',
+                               array( $name ),
+                               ResourceLoader::inDebugMode()
+                       );
                } else {
                        $version = (int)$version > 1 ? (int)$version : 1;
-                       return Xml::encodeJsCall( 'mw.loader.register',
-                               array( $name, $version, $dependencies, $group, $source ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.register',
+                               array( $name, $version, $dependencies, $group, $source ),
+                               ResourceLoader::inDebugMode()
+                       );
                }
        }
 
@@ -1065,14 +1098,21 @@ class ResourceLoader {
         *
         * @param string $id source ID
         * @param array $properties source properties (see addSource())
-        *
         * @return string
         */
        public static function makeLoaderSourcesScript( $id, $properties = null ) {
                if ( is_array( $id ) ) {
-                       return Xml::encodeJsCall( 'mw.loader.addSource', array( $id ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.addSource',
+                               array( $id ),
+                               ResourceLoader::inDebugMode()
+                       );
                } else {
-                       return Xml::encodeJsCall( 'mw.loader.addSource', array( $id, $properties ) );
+                       return Xml::encodeJsCall(
+                               'mw.loader.addSource',
+                               array( $id, $properties ),
+                               ResourceLoader::inDebugMode()
+                       );
                }
        }
 
@@ -1081,7 +1121,6 @@ class ResourceLoader {
         * present.
         *
         * @param string $script JavaScript code
-        *
         * @return string
         */
        public static function makeLoaderConditionalScript( $script ) {
@@ -1093,11 +1132,14 @@ class ResourceLoader {
         * the given value.
         *
         * @param array $configuration List of configuration values keyed by variable name
-        *
         * @return string
         */
        public static function makeConfigSetScript( array $configuration ) {
-               return Xml::encodeJsCall( 'mw.config.set', array( $configuration ), ResourceLoader::inDebugMode() );
+               return Xml::encodeJsCall(
+                       'mw.config.set',
+                       array( $configuration ),
+                       ResourceLoader::inDebugMode()
+               );
        }
 
        /**
@@ -1105,7 +1147,7 @@ class ResourceLoader {
         *
         * For example, array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' )
         * becomes 'foo.bar,baz|bar.baz,quux'
-        * @param array $modules of module names (strings)
+        * @param array $modules List of module names (strings)
         * @return string Packed query string
         */
        public static function makePackedModulesString( $modules ) {
index fdb781b..3642750 100644 (file)
@@ -323,6 +323,16 @@ class SpecialContributions extends IncludableSpecialPage {
                                array(),
                                array( 'page' => $userpage->getPrefixedText() )
                        );
+
+                       # Suppression log link (bug 59120)
+                       if ( $this->getUser()->isAllowed( 'suppressionlog' ) ) {
+                               $tools[] = Linker::linkKnown(
+                                       SpecialPage::getTitleFor( 'Log', 'suppress' ),
+                                       $this->msg( 'sp-contributions-suppresslog' )->escaped(),
+                                       array(),
+                                       array( 'offender' => $username )
+                               );
+                       }
                }
                # Uploads
                $tools[] = Linker::linkKnown(
index d148a50..6c3cb95 100644 (file)
@@ -427,6 +427,15 @@ class DeletedContributionsPage extends SpecialPage {
                                                'page' => $nt->getPrefixedText()
                                        )
                                );
+                               # Suppression log link (bug 59120)
+                               if ( $this->getUser()->isAllowed( 'suppressionlog' ) ) {
+                                       $tools[] = Linker::linkKnown(
+                                               SpecialPage::getTitleFor( 'Log', 'suppress' ),
+                                               $this->msg( 'sp-contributions-suppresslog' )->escaped(),
+                                               array(),
+                                               array( 'offender' => $userObj->getName() )
+                                       );
+                               }
                        }
 
                        # Uploads
index 6695c82..c867f06 100644 (file)
@@ -143,7 +143,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        }
                        $out->addHTML( $this->userForm( $this->mTarget ) );
 
-                       return false;
+                       return;
                }
 
                $this->mTargetObj = $ret;
@@ -159,7 +159,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                $form->loadData();
 
                if ( !wfRunHooks( 'EmailUserForm', array( &$form ) ) ) {
-                       return false;
+                       return;
                }
 
                $result = $form->show();
index 3f49ed3..d5b8d8b 100644 (file)
@@ -75,16 +75,21 @@ if ( !function_exists( 'session_name' ) ) {
 
                <h1>MediaWiki <?php echo htmlspecialchars( $wgVersion ) ?></h1>
                <div class='error'>
-               <p>LocalSettings.php not found.</p>
-               <p>
-               <?php
-               if ( $installerStarted ) {
-                       echo "Please <a href=\"" . htmlspecialchars( $path ) . "mw-config/index." . htmlspecialchars( $ext ) . "\"> complete the installation</a> and download LocalSettings.php.";
-               } else {
-                       echo "Please <a href=\"" . htmlspecialchars( $path ) . "mw-config/index." . htmlspecialchars( $ext ) . "\"> set up the wiki</a> first.";
-               }
-               ?>
-               </p>
+               <?php if ( !file_exists( MW_CONFIG_FILE ) ) { ?>
+                       <p>LocalSettings.php not found.</p>
+                       <p>
+                       <?php
+                       if ( $installerStarted ) {
+                               echo "Please <a href=\"" . htmlspecialchars( $path ) . "mw-config/index." . htmlspecialchars( $ext ) . "\"> complete the installation</a> and download LocalSettings.php.";
+                       } else {
+                               echo "Please <a href=\"" . htmlspecialchars( $path ) . "mw-config/index." . htmlspecialchars( $ext ) . "\"> set up the wiki</a> first.";
+                       }
+                       ?>
+                       </p>
+               <?php } else { ?>
+                       <p>LocalSettings.php not readable.</p>
+                       <p>Please correct file permissions and try again.</p>
+               <?php } ?>
 
                </div>
        </body>
index aa3e4f2..88d57de 100644 (file)
@@ -54,7 +54,8 @@ class UzConverter extends LanguageConverter {
                'ф' => 'f', 'Ф' => 'F',
                'ц' => 'c', 'Ц' => 'C',
                'ў' => 'oʻ', 'Ў' => 'Oʻ',
-               'ц' => 'ts', 'Ц' => 'Ts', // note: at the beginning of a word and right after a consonant, only "s" is used
+               // note: at the beginning of a word and right after a consonant, only "s" is used
+               'ц' => 'ts', 'Ц' => 'Ts',
                'қ' => 'q', 'Қ' => 'Q',
                'ё' => 'yo', 'Ё' => 'Yo',
                'ю' => 'yu', 'Ю' => 'Yu',
@@ -69,9 +70,9 @@ class UzConverter extends LanguageConverter {
                'a' => 'а', 'A' => 'А',
                'b' => 'б', 'B' => 'Б',
                'd' => 'д', 'D' => 'Д',
-               'e' => 'е', 'E' => 'Е',
-               ' e' => ' э', ' E' => ' Э', // "э" is used at the beginning of a word instead of "e"
-               'ye' => 'е', 'Ye' => 'Е',
+               // at the beginning of a word and after a vowel, "э" is used instead of "e"
+               // (see regex below)
+               'e' => 'э', 'E' => 'Э',
                'f' => 'ф', 'F' => 'Ф',
                'g' => 'г', 'G' => 'Г',
                'g‘' => 'ғ', 'G‘' => 'Ғ', 'gʻ' => 'ғ', 'Gʻ' => 'Ғ',
@@ -112,6 +113,18 @@ class UzConverter extends LanguageConverter {
                );
        }
 
+       function translate( $text, $toVariant ) {
+               if( $toVariant == 'uz-cyrl' ) {
+                       $text = str_replace( 'ye', 'е', $text );
+                       $text = str_replace( 'Ye', 'Е', $text );
+                       $text = str_replace( 'YE', 'Е', $text );
+                       // "е" after consonants, otherwise "э" (see above)
+                       $text = preg_replace( '/([BVGDJZYKLMNPRSTFXCWQʻ‘H])E/u', '$1Е', $text );
+                       $text = preg_replace( '/([bvgdjzyklmnprstfxcwqʻ‘h])e/ui', '$1е', $text );
+               }
+               return parent::translate( $text, $toVariant );
+       }
+
 }
 
 /**
index d333a51..57cb6ba 100644 (file)
@@ -1037,9 +1037,9 @@ $2',
 'suspicious-userlogout' => 'رفض طلب خروجك لأنه يبدو كأنه أرسل عن طريق متصفح معطوب أو وسيط تخزين.',
 'createacct-another-realname-tip' => 'الاسم الحقيقي اختياري.
 إذا اخترت توفيره فسيستخدم لنسبة عمل المستخدم إليه.',
-'pt-login' => 'تسجÙ\8aÙ\84 Ø§Ù\84دخÙ\88Ù\84',
-'pt-createaccount' => 'Ø£Ù\86شئ Ø­Ø³Ø§Ø¨Ø§',
-'pt-userlogout' => 'تسجÙ\8aÙ\84 Ø§Ù\84خرÙ\88ج',
+'pt-login' => 'دخول',
+'pt-createaccount' => 'Ø¥Ù\86شاء Ø­Ø³Ø§Ø¨',
+'pt-userlogout' => 'خروج',
 
 # Email sending
 'php-mail-error-unknown' => "خطأ غير معروف في وظيفة البريد PHP's mail()",
@@ -1930,11 +1930,23 @@ $1",
 'rcnotefrom' => "بالأسفل التغييرات منذ '''$2''' (إلى '''$1''' معروضة).",
 'rclistfrom' => 'أظهر التغييرات بدء من $1',
 'rcshowhideminor' => '$1 التعديلات الطفيفة',
+'rcshowhideminor-show' => 'أظهر',
+'rcshowhideminor-hide' => 'أخف',
 'rcshowhidebots' => '$1 البوتات',
+'rcshowhidebots-show' => 'أظهر',
+'rcshowhidebots-hide' => 'أخف',
 'rcshowhideliu' => '$1 {{GENDER:$1|مستخدمين مسجلين|مستخدمات مسجلات|مستخدمون مسجلون}}',
+'rcshowhideliu-show' => 'أظهر',
+'rcshowhideliu-hide' => 'أخف',
 'rcshowhideanons' => '$1 المستخدمين المجهولين',
+'rcshowhideanons-show' => 'أظهر',
+'rcshowhideanons-hide' => 'أخف',
 'rcshowhidepatr' => '$1 التعديلات المراجعة',
+'rcshowhidepatr-show' => 'أظهر',
+'rcshowhidepatr-hide' => 'أخف',
 'rcshowhidemine' => '$1 تعديلاتي',
+'rcshowhidemine-show' => 'أظهر',
+'rcshowhidemine-hide' => 'أخف',
 'rclinks' => 'أظهر آخر $1 تعديل في آخر $2 يوم<br />$3',
 'diff' => 'فرق',
 'hist' => 'تاريخ',
@@ -2915,6 +2927,7 @@ $1',
 'sp-contributions-search' => 'بحث عن مساهمات',
 'sp-contributions-username' => 'عنوان أيبي أو اسم مستخدم:',
 'sp-contributions-toponly' => 'أظهر أعلى المراجعات فقط',
+'sp-contributions-newonly' => 'أظهر إنشاء الصفحات فقط',
 'sp-contributions-submit' => 'بحث',
 
 # What links here
index d9a3276..04af676 100644 (file)
@@ -97,7 +97,7 @@ $messages = array(
 'tog-hidepatrolled' => 'Без паказу ўхваленых правак у нядаўніх змяненнях',
 'tog-newpageshidepatrolled' => 'Без паказу ўхваленых правак у пераліку новых старонак',
 'tog-extendwatchlist' => 'Паказваць усе змяненні, а не толькі апошнія',
-'tog-usenewrc' => 'Групаваць змены старонкі ў спісах апошніх зменаў і назіранняў (патрабуе JavaScript)',
+'tog-usenewrc' => 'Групаваць змены па старонках у апошніх зменах і спісе назірання',
 'tog-numberheadings' => 'Аўта-нумараваць падзагалоўкі',
 'tog-showtoolbar' => 'Паказваць рэдактарскую стужку (Яваскрыпт)',
 'tog-editondblclick' => 'Праўка старонак па падвойным пстрыку (Яваскрыпт)',
@@ -231,7 +231,7 @@ $messages = array(
 'cancel' => 'Нічога',
 'moredotdotdot' => 'Яшчэ...',
 'morenotlisted' => 'Больш нічога няма...',
-'mypage' => 'УлаÑ\81наÑ\8f Ñ\81таронка',
+'mypage' => 'Старонка',
 'mytalk' => 'Размовы',
 'anontalk' => 'Размова для гэтага IP',
 'navigation' => 'Навігацыя',
@@ -331,7 +331,7 @@ $1',
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).
 'aboutsite' => 'Пра {{GRAMMAR:вінавальны|{{SITENAME}}}}',
 'aboutpage' => 'Project:Пра {{GRAMMAR:вінавальны|{{SITENAME}}}}',
-'copyright' => 'Матэрыял даступны на ўмовах $1.',
+'copyright' => 'Матэрыял даступны на ўмовах $1 (калі не пазначана іншае).',
 'copyrightpage' => '{{ns:project}}:Аўтарскія правы',
 'currentevents' => 'Актуальныя падзеі',
 'currentevents-url' => 'Project:Актуальныя падзеі',
@@ -464,6 +464,7 @@ $2',
 'ns-specialprotected' => 'Не дазволена правіць старонкі ў прасторы назваў {{ns:special}}.',
 'titleprotected' => "Назва засцерагаецца ад стварэння; ахова пастаўлена ўдзельнікам: [[User:$1|$1]].
 Тлумачэнне пастаноўкі пад ахову: ''$2''.",
+'exception-nologin' => 'Вы не ўвайшлі ў сістэму',
 
 # Virus scanner
 'virus-badscanner' => "Некарэктная канфігурацыя: невядомы антывірусны сканер: ''$1''",
@@ -480,6 +481,7 @@ $2',
 'yourname' => 'Імя ўдзельніка',
 'userlogin-yourname' => 'Імя ўліковага запісу',
 'userlogin-yourname-ph' => 'Увядзіце імя вашага ўліковага запісу',
+'createacct-another-username-ph' => 'Увядзіце імя карыстальніка',
 'yourpassword' => 'Пароль',
 'userlogin-yourpassword' => 'Пароль',
 'userlogin-yourpassword-ph' => 'Увядзіце ваш пароль',
@@ -500,18 +502,28 @@ $2',
 'logout' => 'Выйсці з сістэмы',
 'userlogout' => 'Выйсці з сістэмы',
 'notloggedin' => 'Не ўвайшоў',
+'userlogin-noaccount' => 'Не маеце ўліковага запісу?',
 'nologin' => 'Не маеце рахунку? $1.',
 'nologinlink' => 'Завесці рахунак',
 'createaccount' => 'Стварыць рахунак',
 'gotaccount' => "Ужо маеце рахунак? '''$1'''.",
 'gotaccountlink' => 'Увайсці ў сістэму',
 'userlogin-resetlink' => 'Забыліся даныя для ўваходу?',
+'userlogin-resetpassword-link' => 'Забылі пароль?',
+'createacct-emailrequired' => 'Адрас электроннай пошты',
+'createacct-emailoptional' => 'Адрас электроннай пошты (неабавязкова)',
+'createacct-email-ph' => 'Увядзіце ваш адрас электроннай пошты',
+'createacct-another-email-ph' => 'Увядзіце адрас электроннай пошты',
 'createaccountmail' => 'праз эл.пошту',
 'createaccountreason' => 'Прычына:',
+'createacct-reason' => 'Прычына',
+'createacct-imgcaptcha-ph' => 'Увядзіце тэкст, які вы бачыце вышэй',
+'createacct-submit' => 'Стварыць уліковы запіс',
 'badretype' => 'Уведзеныя паролі не аднолькавыя.',
 'userexists' => 'Такое імя ўдзельніка ўжо занятае.
 Калі ласка, выбярыце іншае імя.',
 'loginerror' => 'Памылка ўваходу',
+'createacct-error' => 'Памылка стварэння ўліковага запісу',
 'createaccounterror' => 'Не ўдалося стварыць рахунак: $1',
 'nocookiesnew' => 'Рахунак быў створаны, але ў сістэму вы не ўвайшлі. {{SITENAME}} карыстаецца квіткамі (кукі), каб апрацоўваць уваходы ўдзельнікаў, а гэтая функцыянальнасць адключана ў вашым браўзеры. Уключыце квіткі ў браўзеры, тады ўваходзьце са сваімі новымі імем удзельніка і паролем.',
 'nocookieslogin' => '{{SITENAME}} карыстаецца квіткамі (кукі), каб пазнаваць удзельнікаў. У вашым браўзеры квіткі не дазволены. Дазвольце іх працу і паспрабуйце ізноў.',
@@ -529,7 +541,7 @@ $2',
 'passwordtooshort' => 'Трэба, каб у паролі было найменей {{PLURAL:$1|1 знак|$1 знакаў}}.',
 'password-name-match' => 'Ваш пароль павінен адрознівацца ад імя карыстальніка.',
 'password-login-forbidden' => 'Выкарыстанне гэтага імя карыстальніка і пароля было забаронена.',
-'mailmypassword' => 'Ð\90даÑ\81лаÑ\86Ñ\8c Ð½Ð¾Ð²Ñ\8b Ð¿Ð°Ñ\80олÑ\8c Ñ\8dл.поÑ\88Ñ\82ай',
+'mailmypassword' => 'СкÑ\96нÑ\83Ñ\86Ñ\8c Ð¿Ð°Ñ\80олÑ\8c',
 'passwordremindertitle' => 'Нагаданне пра пароль ад {{SITENAME}}',
 'passwordremindertext' => 'Нехта (магчыма, што вы, з адрасу IP $1) папрасіў выслаць новы пароль для пляцоўкі {{SITENAME}} ($4). Для ўдзельніка "$2" быў створаны тымчасовы пароль: "$3".
 Калі вы хацелі менавіта гэтага, то ўвайдзіце ў сістэму і выберыце сабе новы пароль. Тымчасовы пароль будзе дзейным на працягу {{PLURAL:$5|аднаго дня|$5 дзён}}.
@@ -563,6 +575,9 @@ $2',
 'login-abort-generic' => 'Няўдалая спроба ўвайсці ў сістэму',
 'loginlanguagelabel' => 'Мова: $1',
 'suspicious-userlogout' => 'Ваш запыт на выхад быў адмоўлены, паколькі ён выглядае як накіраваны са зламанага браўзера або кэшаванне проксі-сервераў.',
+'pt-login' => 'Увайсці',
+'pt-createaccount' => 'Стварыць уліковы запіс',
+'pt-userlogout' => 'Выйсці',
 
 # Email sending
 'php-mail-error-unknown' => 'Невядомая памылка ў функцыі PHP-пошты',
@@ -570,13 +585,13 @@ $2',
 
 # Change password dialog
 'changepassword' => 'Пароль',
-'resetpass_announce' => 'Ð\92Ñ\8b Ñ\9eвайÑ\88лÑ\96 Ñ\9e Ñ\81Ñ\96Ñ\81Ñ\82Ñ\8dмÑ\83 Ð¿Ð°Ð´ Ñ\82Ñ\8bмÑ\87аÑ\81овÑ\8bм Ð¿Ð°Ñ\80олем, Ð¿Ñ\80Ñ\8bÑ\81ланÑ\8bм Ñ\8dл.поÑ\88Ñ\82ай. Ð\9aаб Ð¿Ñ\80авÑ\96лÑ\8cна Ð°Ñ\84оÑ\80мÑ\96Ñ\86Ñ\8c Ñ\83ваÑ\85од, Ð½Ð°Ð»ÐµÐ¶Ñ\8bÑ\86Ñ\8c Ð²Ñ\8bзнаÑ\87Ñ\8bÑ\86Ñ\8c Ð½Ð¾Ð²Ñ\8b Ð¿Ð°Ñ\80олÑ\8c Ð²Ð¾Ñ\81Ñ\8c Ñ\82Ñ\83Ñ\82:',
+'resetpass_announce' => 'Ð\9aаб Ð·Ð°Ð²Ñ\8fÑ\80Ñ\88Ñ\8bÑ\86Ñ\8c Ñ\83ваÑ\85од Ñ\83 Ñ\81Ñ\96Ñ\81Ñ\82Ñ\8dмÑ\83, Ð\92Ñ\8b Ð¿Ð°Ð²Ñ\96ннÑ\8b Ñ\9eÑ\81Ñ\82анавÑ\96Ñ\86Ñ\8c Ð½Ð¾Ð²Ñ\8b Ð¿Ð°Ñ\80олÑ\8c.',
 'resetpass_header' => 'Змяніць пароль рахунку',
 'oldpassword' => 'Стары пароль:',
 'newpassword' => 'Новы пароль:',
 'retypenew' => 'Новы пароль паўторна:',
 'resetpass_submit' => 'Наставіць пароль і ўвайсці',
-'changepassword-success' => 'Ваш пароль паспяхова зменены! Цяпер уваходзім...',
+'changepassword-success' => 'Ваш пароль паспяхова зменены!',
 'resetpass_forbidden' => 'Не дазволена мяняць паролі',
 'resetpass-no-info' => 'Трэба ўвайсці ў сістэму, каб звяртацца да гэтай старонкі наўпрост.',
 'resetpass-submit-loggedin' => 'Змяніць пароль',
@@ -1929,12 +1944,12 @@ $1',
 'watchlistanontext' => 'Каб паглядзець ці змяніць спіс назірання, трэба $1.',
 'watchnologin' => 'Без прадстаўлення',
 'watchnologintext' => 'Каб правіць свой спіс назірання, трэба [[Special:UserLogin|ўвайсці ў сістэму]].',
-'addwatch' => 'Дадаць у назіранае',
+'addwatch' => 'Дадаць у спіс назірання',
 'addedwatchtext' => "Старонка \"[[:\$1]]\" была дададзена да [[Special:Watchlist|назіраных]] вамі.
 Змяненні, якія адбудуцца з гэтай старонкай і з Размовай пра яе, будуць паказвацца там, і старонка будзе '''вылучацца шрыфтам''' у [[Special:RecentChanges|спісе нядаўніх змяненняў]], каб лягчэй пазнаваць яе.
 
 Калі вы не пажадаеце больш назіраць за гэтай старонкай, націсніце \"Не назіраць\" у бакоўцы.",
-'removewatch' => 'Выдаліць са спісу назірання',
+'removewatch' => 'Выдаліць са спіса назірання',
 'removedwatchtext' => 'Старонка "[[:$1]]" была вынята з вашага [[Special:Watchlist|спіса назірання]].',
 'watch' => 'Назіраць',
 'watchthispage' => 'Назіраць за гэтай старонкай',
@@ -2009,8 +2024,8 @@ $UNWATCHURL
 Пацвердзіце свой намер зрабіць гэта, сваё разуменне наступстваў, і што вы робіце гэта ў адпаведнасці з [[{{MediaWiki:Policy-url}}|палітыкай (асноўнымі правіламі)]].',
 'actioncomplete' => 'Завершана аперацыя',
 'actionfailed' => 'Памылка дзеяння',
-'deletedtext' => '"$1" было выдалена.
\91аÑ\87 $2 Ð¿Ð° Ð¶Ñ\83Ñ\80нал Ð½Ñ\8fдаÑ\9eнÑ\96Ñ\85 Ð²Ñ\8bдаленнÑ\8fÑ\9e.',
+'deletedtext' => 'Старонка "$1" была выдалена.
\97апÑ\96Ñ\81Ñ\8b Ð°Ð± Ð½Ñ\8fдаÑ\9eнÑ\96Ñ\85 Ð²Ñ\8bдаленнÑ\8fÑ\85 Ð³Ð». Ñ\9e $2.',
 'dellogpage' => 'Журнал сціранняў',
 'dellogpagetext' => 'Ніжэй паказаны спіс самых нядаўніх сціранняў.',
 'deletionlog' => 'журнал сціранняў',
@@ -2139,7 +2154,7 @@ $UNWATCHURL
 'undeletedpage' => "'''$1 была адноўлена'''
 
 Праверце пералік нядаўніх сціранняў і аднаўленняў у [[Special:Log/delete|журнале сціранняў]].",
-'undelete-header' => 'Ð\91аÑ\87 Ð½Ñ\8fдаÑ\9eна Ñ\81Ñ\86Ñ\91Ñ\80Ñ\82Ñ\8bÑ\8f Ñ\81Ñ\82аÑ\80онкÑ\96 Ñ\9e [[Special:Log/delete|журнале сціранняў]].',
+'undelete-header' => 'Ð\9dÑ\8fдаÑ\9eна Ñ\81Ñ\86Ñ\91Ñ\80Ñ\82Ñ\8bÑ\8f Ñ\81Ñ\82аÑ\80онкÑ\96 Ð¼Ð¾Ð¶Ð½Ð° Ð¿Ð°Ð³Ð»Ñ\8fдзеÑ\86Ñ\8c Ñ\83 [[Special:Log/delete|журнале сціранняў]].',
 'undelete-search-title' => 'Пошук выдаленых старонак',
 'undelete-search-box' => 'Знайсці ў сцёртых старонках',
 'undelete-search-prefix' => 'Паказаць старонкі, пачынаючы з:',
@@ -2295,7 +2310,7 @@ $1',
 'blocklog-showlog' => '{{GENDER:$1|Гэты ўдзельнік ужо блакіраваўся|Гэта ўдзельніца ўжо блакіравалася}} раней.
 Ніжэй прыведзены журнал блакіровак:',
 'blocklog-showsuppresslog' => 'Гэты ўдзельнік ужо заблакаваны і скрыты. Журнал утойвання прыведзены ніжэй:',
-'blocklogentry' => 'пастаўлены блок на "[[$1]]", з часам трывання $2 $3',
+'blocklogentry' => 'паставіў блок на "[[$1]]", з часам трывання $2 $3',
 'reblock-logentry' => 'змененыя настройкі блока для [[$1]] з часам згасання $2 $3',
 'blocklogtext' => 'Журнал пастаноўкі і здымання блокаў. Аўтаматычна блакаваныя адрасы IP тут не паказваюцца. Спіс актуальных забарон і блокаў бач у [[Special:BlockList|спісе блокаў IP]].',
 'unblocklogentry' => 'зняты блок з $1',
@@ -3286,15 +3301,15 @@ $5
 'watchlistedit-raw-legend' => 'Правіць нефарматаваны спіс назірання',
 'watchlistedit-raw-explain' => 'Назвы старонак з ліку назіраных паказаныя ніжэй, без афармлення, адна назва на адзін радок; такім чынам, спіс можна правіць як звычайны тэкст. Па сканчэнні націсніце "{{int:Watchlistedit-raw-submit}}". Таксама гэта можна зрабіць праз [[Special:EditWatchlist|стандартны інтэрфейс]].',
 'watchlistedit-raw-titles' => 'Назвы:',
-'watchlistedit-raw-submit' => 'Абнавіць Назіранае',
+'watchlistedit-raw-submit' => 'Абнавіць спіс назірання',
 'watchlistedit-raw-done' => 'Спіс назірання абноўлены.',
 'watchlistedit-raw-added' => 'Дапісаны{{PLURAL:$1| 1 складнік|я $1 складнікаў}}:',
 'watchlistedit-raw-removed' => 'Выняты{{PLURAL:$1| 1 складнік|я $1 складнікаў}}:',
 
 # Watchlist editing tools
 'watchlisttools-view' => 'Паказаць змяненні',
-'watchlisttools-edit' => 'Паказаць назіранае',
-'watchlisttools-raw' => 'Паказаць нефарматаванае назіранае',
+'watchlisttools-edit' => 'Паказаць спіс назірання',
+'watchlisttools-raw' => 'Паказаць нефарматаваны спіс назірання',
 
 # Signatures
 'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|размовы]])',
index 140448d..50d6588 100644 (file)
@@ -386,7 +386,7 @@ $messages = array(
 'category-empty' => "''Гэтая катэгорыя ня ўтрымлівае ні старонак, ні файлаў.''",
 'hidden-categories' => '{{PLURAL:$1|1=Схаваная катэгорыя|Схаваныя катэгорыі}}',
 'hidden-category-category' => 'Схаваныя катэгорыі',
-'category-subcat-count' => '{{PLURAL:$2|Гэтая катэгорыя зьмяшчае наступную падкатэгорыю.|Гэтая катэгорыя зьмяшчае {{PLURAL:$1|наступную $1 падкатэгорыю|наступныя $1 падкатэгорыі|наступныя $1 падкатэгорыяў}} з $2 агулам.}}',
+'category-subcat-count' => '{{PLURAL:$2|1=Гэтая катэгорыя зьмяшчае наступную падкатэгорыю.|Гэтая катэгорыя зьмяшчае {{PLURAL:$1|наступную $1 падкатэгорыю|наступныя $1 падкатэгорыі|наступныя $1 падкатэгорыяў}} з $2 агулам.}}',
 'category-subcat-count-limited' => 'У гэтай катэгорыі $1 {{PLURAL:$1|падкатэгорыя|падкатэгорыі|падкатэгорыяў}}.',
 'category-article-count' => '{{PLURAL:$2|1=Гэтая катэгорыя ўтрымлівае толькі адну старонку.|{{PLURAL:$1|Паказаная $1 старонка|Паказаныя $1 старонкі|Паказаныя $1 старонак}} гэтай катэгорыі з $2.}}',
 'category-article-count-limited' => 'У гэтай катэгорыі $1 {{PLURAL:$1|старонка|старонкі|старонак}}.',
@@ -833,7 +833,7 @@ $2',
 'resetpass-temp-password' => 'Часовы пароль:',
 'resetpass-abort-generic' => 'Зьмяненьне паролю было скасаванае пашырэньнем.',
 'resetpass-expired' => 'Тэрмін дзеяньня вашага паролю скончыўся. Калі ласка, пазначце новы пароль для ўваходу ў сыстэму.',
-'resetpass-expired-soft' => 'Тэрмін дзеяньня вашага паролю скончыўся і ён патрабуе замены. Калі ласка, абярыце новы пароль цяпер або націсьніце «Скасаваць», каб зьмяніць яго пазьней.',
+'resetpass-expired-soft' => 'Тэрмін дзеяньня вашага паролю скончыўся і ён патрабуе замены. Калі ласка, абярыце новы пароль цяпер або націсьніце «{{int:resetpass-submit-cancel}}», каб зьмяніць яго пазьней.',
 
 # Special:PasswordReset
 'passwordreset' => 'Ачыстка паролю',
@@ -1678,7 +1678,7 @@ $1",
 'recentchanges-label-plusminus' => 'Памер старонкі зьмяніўся на такую колькасьць байтаў',
 'recentchanges-legend-heading' => "'''Легенда:'''",
 'recentchanges-legend-newpage' => '(глядзіце таксама [[Special:NewPages|сьпіс новых старонак]])',
-'rcnotefrom' => "Ніжэй знаходзяцца зьмены з '''$2''' (да '''$1''' на старонку).",
+'rcnotefrom' => 'Ніжэй знаходзяцца зьмены з <strong>$2</strong> (да <strong>$1</strong> на старонку).',
 'rclistfrom' => 'Паказаць зьмены з $1',
 'rcshowhideminor' => '$1 дробныя праўкі',
 'rcshowhideminor-show' => 'Паказаць',
@@ -1687,9 +1687,17 @@ $1",
 'rcshowhidebots-show' => 'Паказаць',
 'rcshowhidebots-hide' => 'Схаваць',
 'rcshowhideliu' => '$1 зарэгістраваных карыстальнікаў',
+'rcshowhideliu-show' => 'Паказаць',
+'rcshowhideliu-hide' => 'Схаваць',
 'rcshowhideanons' => '$1 ананімаў',
+'rcshowhideanons-show' => 'Паказаць',
+'rcshowhideanons-hide' => 'Схаваць',
 'rcshowhidepatr' => '$1 патруляваныя праўкі',
+'rcshowhidepatr-show' => 'Паказаць',
+'rcshowhidepatr-hide' => 'Схаваць',
 'rcshowhidemine' => '$1 мае праўкі',
+'rcshowhidemine-show' => 'Паказаць',
+'rcshowhidemine-hide' => 'Схаваць',
 'rclinks' => 'Паказаць апошнія $1 зьменаў за мінулыя $2 дзён<br />$3',
 'diff' => 'розьн',
 'hist' => 'гіст',
@@ -1815,6 +1823,7 @@ $1",
 'uploaddisabledtext' => 'Загрузка файлаў забароненая.',
 'php-uploaddisabledtext' => 'Загрузка файлаў была адключаная ў парамэтрах канфігурацыі PHP. Калі ласка, праверце значэньне парамэтра «file_uploads».',
 'uploadscripted' => 'Гэты файл утрымлівае HTML-код альбо скрыпт, які можа памылкова апрацоўвацца браўзэрам.',
+'uploadscriptednamespace' => 'Гэты SVG-файл утрымлівае няслушную прастору назваў «$1»',
 'uploadinvalidxml' => 'Не атрымалася прааналізаваць XML у загружаным файле.',
 'uploadvirus' => 'Файл утрымлівае вірус! Падрабязнасьці: $1',
 'uploadjava' => 'Файл зьяўляецца ZIP-архівам, які зьмяшчае .class-файл Java.
@@ -4070,7 +4079,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'api-error-badtoken' => 'Унутраная памылка: няслушны ключ.',
 'api-error-copyuploaddisabled' => 'Загрузка з URL-адрасу забароненая на гэтым сэрвэры.',
 'api-error-duplicate' => 'Ужо {{PLURAL:$1|1=існуе [$2 іншы файл]|існуюць [$2 іншыя файлы]}} з такім жа зьместам.',
-'api-error-duplicate-archive' => 'Раней на сайце {{PLURAL:$1|1=ўжо быў [$2 файл]|былі [$2 файлы]}} з дакладна такім жа зьместам, але {{PLURAL:$1|1=ён быў выдалены|яны былі выдаленыя}}.',
+'api-error-duplicate-archive' => 'Раней на сайце {{PLURAL:$1|1=быў [$2 файл]|былі [$2 файлы]}} з дакладна такім жа зьместам, але {{PLURAL:$1|1=ён быў выдалены|яны былі выдаленыя}}.',
 'api-error-duplicate-archive-popup-title' => 'Дублікаты {{PLURAL:$1|1=файла, які ўжо быў выдалены|файлаў, якія ўжо былі выдаленыя}}',
 'api-error-duplicate-popup-title' => '{{PLURAL:$1|1=Ідэнтычны файл|Ідэнтычныя файлы}}',
 'api-error-empty-file' => 'Дасланы Вамі файл быў пусты.',
index ac198f4..61697d8 100644 (file)
@@ -605,6 +605,9 @@ $2',
 'suspicious-userlogout' => 'আপনার প্রস্থানের অনুরোধ বাতিল হয়েছে কারণ অনুমিত যে আপনার ব্রাউজার অসম্পূর্ণ অথবা পূবর্বতী তথ্য প্রেরণ করেছে।',
 'createacct-another-realname-tip' => 'আসল নাম ঐচ্ছিক।
 আপনি যদি তা দিতে চান, তাহলে তা ব্যবহারকারীকে তাদের কাজের জন্য স্বীকৃতিদানে ব্যবহার করা হবে।',
+'pt-login' => 'প্রবেশ',
+'pt-createaccount' => 'অ্যাকাউন্ট তৈরি করুন',
+'pt-userlogout' => 'প্রস্থান',
 
 # Email sending
 'php-mail-error-unknown' => 'পিএইচপি এর মেইল () কার্যে অজ্ঞাত ভুল',
@@ -634,7 +637,7 @@ $2',
 'resetpass-temp-password' => 'অস্থায়ী শব্দচাবি:',
 'resetpass-abort-generic' => 'শব্দচাবি পরিবর্তন একটি এক্সটেনশনের কারণে স্থগিত করা হয়েছে।',
 'resetpass-expired' => 'আপনার পাসওয়ার্ডের মেয়াদ উত্তীর্ণ হয়েছে। অনুগ্রহ করে নতুন পাসওয়ার্ড নির্ধারণ করুন।',
-'resetpass-expired-soft' => 'আপনার পাসওয়ার্ড মেয়াদ উত্তীর্ণ হয়েছে, এবং আপনাকে একটি নতুন পাসওয়ার্ড নির্ধারণ করতে হবে। অনুগ্রহ করে এখনই একটি নতুন পাসওয়ার্ড নির্ধারণ করুন অথবা পরে পরিবর্তন করতে চাইলে বাতিল বাটনে ক্লিক করুন।',
+'resetpass-expired-soft' => 'আপনার পাসওয়ার্ডের মেয়াদ উত্তীর্ণ হয়েছে এবং আপনাকে একটি নতুন পাসওয়ার্ড নির্ধারণ করতে হবে। অনুগ্রহ করে এখনই একটি নতুন পাসওয়ার্ড নির্ধারণ করুন অথবা পরে পরিবর্তন করতে চাইলে "{{int:resetpass-submit-cancel}}" বাটনে ক্লিক করুন।',
 
 # Special:PasswordReset
 'passwordreset' => 'শব্দচাবি রিসেট',
@@ -1157,6 +1160,7 @@ $1",
 'searchrelated' => 'সম্পর্কিত',
 'searchall' => 'সমস্ত',
 'showingresults' => "নিচে '''$2''' নং থেকে শুরু করে {{PLURAL:$1|'''1''' ফলাফল|'''$1''' ফলাফলসমূহ}} দেখানো হল।",
+'showingresultsinrange' => '#<strong>$2</strong> থেকে #<strong>$3</strong> পরিসীমার মধ্যে {{PLURAL:$1|<strong>১টি</strong> ফলাফল|<strong>$1টি</strong> ফলাফল}} নিচে দেখানো হচ্ছে।',
 'showingresultsnum' => "নিম্নে {{PLURAL:$3|'''1''' ফলাফল|'''$3''' ফলাফলসমূহ}} দেখানো হয়েছে যা শুরু হয়েছে #'''$2''' দিয়ে।",
 'showingresultsheader' => "'''$4''' এর জন্য {{PLURAL:$5|ফলাফল '''$3''' এর '''$1'''|ফলাফলসমূহ '''$3''' এর মধ্যে '''$1 - $2'''}}",
 'search-nonefound' => 'খোঁজকৃত পাতার সাথে মিলে যায় এমন কোনো ফলাফল নেই।',
@@ -1472,14 +1476,26 @@ $1",
 'recentchanges-legend-heading' => "'''ব্যাখ্যামূলক বর্ণনা:'''",
 'recentchanges-legend-newpage' => '(আরও দেখুন [[Special:NewPages|নতুন পাতার তালিকা]])',
 'recentchanges-legend-plusminus' => "(''±১২৩'')",
-'rcnotefrom' => "'''$2'''-এর পরে সংঘটিত পরিবর্তনগুলো নিচে দেখানো হল ('''$1'''টি)।",
-'rclistfrom' => '$1-এর পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও।',
+'rcnotefrom' => '<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)',
+'rclistfrom' => '$2, $3 তারিখের পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও',
 'rcshowhideminor' => 'অনুল্লেখ্য পরিবর্তনগুলো $1',
+'rcshowhideminor-show' => 'দেখাও',
+'rcshowhideminor-hide' => 'আড়াল করো',
 'rcshowhidebots' => 'বটগুলো $1',
+'rcshowhidebots-show' => 'দেখাও',
+'rcshowhidebots-hide' => 'আড়াল করো',
 'rcshowhideliu' => 'নিবন্ধিত ব্যবহারকারীদের $1',
+'rcshowhideliu-show' => 'দেখাও',
+'rcshowhideliu-hide' => 'আড়াল করো',
 'rcshowhideanons' => 'বেনামী ব্যবহারকারীদের $1',
+'rcshowhideanons-show' => 'দেখাও',
+'rcshowhideanons-hide' => 'আড়াল করো',
 'rcshowhidepatr' => 'পরীক্ষিত সম্পাদনা $1',
+'rcshowhidepatr-show' => 'দেখাও',
+'rcshowhidepatr-hide' => 'আড়াল করো',
 'rcshowhidemine' => 'আমার সম্পাদনাগুলো $1',
+'rcshowhidemine-show' => 'দেখাও',
+'rcshowhidemine-hide' => 'আড়াল করো',
 'rclinks' => "'''প্রদর্শনের ধরন'''<br />
 * বিগত ($2) দিনের শেষ ($1)টি পরিবর্তন দেখাও
 * $3",
index 8840063..37183a6 100644 (file)
@@ -34,35 +34,41 @@ $messages = array(
 'tog-hidepatrolled' => 'ཉེ་དུས་ཀྱི་ལྟ་ཞིབ་བྱས་པའི་རྩོམ་སྒྲིག་རྣམས་སྦས།',
 'tog-newpageshidepatrolled' => 'ཤོག་ངོས་གསར་བར་ལྟ་ཞིབ་བྱས་པའི་རྩོམ་སྒྲིག་ཀྱི་ཤོག་ངོས་སྦས།',
 'tog-extendwatchlist' => 'ལྟ་ཞིབ་ཐོ་རྒྱ་སྐྱེད་ཏེ་ཉེ་ལམ་ཙམ་མིན་པར་བཟོ་བཅོས་ཡོངས་རྫོགས་སྟོན་ཅིག',
-'tog-usenewrc' => 'ཡརà¼\8bརà¾\92ྱསà¼\8bà½\85à½\93à¼\8bà½\82ྱིà¼\8bà½\89ེà¼\8bà½\96འིà¼\8bà½\96à½\9fོà¼\8bà½\96à½\85ོསà¼\8bà½\96ེà½\91à¼\8bསྤྱོà½\91à¼\8bà½\94à¼\8d(Java à½¡à½²à¼\8bà½\96རྡà¼\8bà½\86à½\91à¼\8bà½\91à½\82ོས)',
+'tog-usenewrc' => 'à½\89ེà¼\8bà½\96འིà¼\8bà½\96à½\9fོà¼\8bà½\96à½\85ོསà¼\8bà½\91à½\84à¼\8bà½\91à½\82སà¼\8bའà½\91ེà½\98སà¼\8bཤོà½\82à¼\8bà½\84ོསà¼\8bà½\80ྱིà¼\8bà½\96à½\85ོསà¼\8bའà½\82ྱུརà¼\8bརà¾\90ྱེà½\93à¼\8bà½\94སà¼\8bསྡེà¼\8bà½\9aà½\93à¼\8bà½\96à½\85ོསà¼\8bའà½\82ྱུརà¼\8bà½\95ྱིà½\93à¼\8bའà½\91ུà½\82à¼\8d',
 'tog-numberheadings' => 'རང་སྒྲིག་ཨང་རྟགས་འགོ་བརྗོད།',
 'tog-showtoolbar' => 'རྩོམ་སྒྲིག་ལག་ཆ་སྟོན། (JavaScript ཡི་བརྡ་ཆད་དགོས།)',
 'tog-editondblclick' => 'ཤོག་ངོས་རྩོམ་སྒྲིག་བྱེད་པར་ལན་གཉིས་རྡེབ།',
+'tog-editsectiononrightclick' => 'དུམ་འཚམས་ཀྱི་འགོ་འརྗོད་ལ་འཐེབ་གཞོང་གཡས་པ་གནོན་ཏེ་དུམ་འཚམས་བཟོ་འཅོས་བྱེད་རོགས།',
 'tog-rememberpassword' => 'ངའི་ནང་འཛུལ་བཤར་ཆས་འདི་སྟེང་(མང་མཐར་ཉིན $1 དྲན་པར་མཛོད། )',
-'tog-watchcreations' => 'ངའི་ལྟ་ཐོའི་གྲས་སུ་གསར་བཟོ་བྱས་པ་ལ་ཤོག་ངོས་ཁ་སྣོན།',
-'tog-watchdefault' => 'ངའི་ལྟ་ཐོའི་གྲས་སུ་རྩོམ་སྒྲིག་བྱས་པ་ལ་ཤོག་ངོས་ཁ་སྣོན།',
-'tog-watchmoves' => 'ངའི་ལྟ་ཐོའི་གྲས་སུ་སྤོར་བ་ལ་ཤོག་ངོས་ཁ་སྣོན།',
-'tog-watchdeletion' => 'ངའི་ལྟ་ཐོའི་གྲས་སུ་དོར་བ་ལ་ཤོག་ངོས་ཁ་སྣོན།',
-'tog-previewontop' => 'རྩོམ་སྒྲིག་སྒྲོམ་གྱི་གོང་སྔོན་ལྟའི་དཔེ་གཟུགས་སྟོན།',
+'tog-watchcreations' => 'ངས་གསར་བཟོ་བྱས་པའི་ཤོག་ངོས་དང་ཡིག་ཆ་ཡར་འཇུག་བྱས་པ་རྣམས་ངའི་དགའ་འདེམས་ཐོ་ལ་སྣོན་རོགས།',
+'tog-watchdefault' => 'ངས་ཁ་སྣོན་བྱས་པའི་ཤོག་ངོས་དང་ཡིག་ཆ་རྣམས་ངའི་ལྟ་ཞིབ་ཐོ་ནང་སྣོན་རོགས།',
+'tog-watchmoves' => 'ངས་ཤོག་ངོས་དང་ཡིག་ཆ་ཕན་ཚུན་སྤོར་བ་རྣམས་ངའི་ལྟ་ཞིབ་ཐོའི་ནང་སྣོན་རོགས།',
+'tog-watchdeletion' => 'ངས་ཤོག་ངོས་དང་ཡིག་ཆ་སུབ་འདོར་བྱས་པ་རྣམས་ངའི་ལྟ་ཞིབ་ཐོའི་ནང་སྣོན་རོགས།',
+'tog-minordefault' => 'ཁ་སྣོན་རྩོམ་སྒྲིག་རྣམས་རང་འགུལ་གྱིས་རྩོམ་སྒྲིག་ཕལ་པར་རྟགས་རྒྱོབ་རོགས།',
+'tog-previewontop' => 'རྩོམ་སྒྲིག་སྒྲོམ་གྱི་སྟེང་སྔོན་ལྟའི་དཔེ་གཟུགས་སྟོན།',
 'tog-previewonfirst' => 'ཐེངས་དང་པོའི་རྩོམ་སྒྲིག་སྟེང་དུ་སྔོན་ལྟའི་དཔེ་གཟུགས་སྟོན།',
-'tog-enotifwatchlistpages' => 'à½\84འིà¼\8bལà¾\9fà¼\8bà½\90ོའིà¼\8bཤོà½\82à¼\8bà½\84ོསà¼\8bལà¼\8bà½\96à½\9fོà¼\8bà½\96à½\85ོསà¼\8bà½\96ྱུà½\84à¼\8bà½\9aེà¼\8bà½\82ློà½\82à¼\8bའà½\95ྲིà½\93à¼\8bà½\82à½\8fང་རོགས།',
+'tog-enotifwatchlistpages' => 'à½\84འིà¼\8bལà¾\9fà¼\8bà½\9eིà½\96à¼\8bà½\90ོà¼\8bà½\93à½\84à¼\8bà½\82ིà¼\8bཤོà½\82à¼\8bà½\84ོསà¼\8bà½\91à½\84à¼\8bཡིà½\82à¼\8bà½\86à¼\8bརྣà½\98སà¼\8bལà¼\8bའà½\82ྱུརà¼\8bལྡོà½\82à¼\8bà½\96ྱུà½\84à¼\8bà½\9aེà¼\8bà½\84à¼\8bལà¼\8bà½\82ློà½\82à¼\8bའà½\95ྲིà½\93à¼\8bà½\82à½\8fོང་རོགས།',
 'tog-enotifusertalkpages' => 'ངའི་སྤྱོད་མིའི་གླེང་མོལ་ལ་བཟོ་བཅོས་བྱུང་ཚེ་གློག་འཕྲིན་གཏང་རོགས།',
-'tog-enotifminoredits' => 'རྩོམ་སྒྲིག་ཆུང་ཚགས་རིགས་ལའང་གློག་འཕྲིན་གཏོང་རོགས།',
+'tog-enotifminoredits' => 'རྩོམ་སྒྲིག་དང་ཡིག་ཆར་བཟོ་བཅོས་ཆུང་ཚགས་རིགས་བྱུང་ན་ཡང་གློག་འཕྲིན་གཏོང་རོགས།',
+'tog-enotifrevealaddr' => 'ངའི་གློག་འཕྲིན་ཁ་བྱང་འདི་བརྡ་ཐོའི་ཁ་བྱང་ནང་གསལ་སྟོན་བྱེད་རོགས།',
 'tog-shownumberswatching' => 'ཤོག་ངོས་ལ་ལྟ་བཞིན་པའི་སྤྱོད་མིའི་ཁ་གྲངས་སྟོན།',
 'tog-oldsig' => 'ད་ཡོད་མིང་རྟགས།',
 'tog-watchlisthideown' => 'ངའི་རྩོམ་སྒྲིག་རྣམས་ལྟ་ཞིབ་ཐོ་ལས་སྦས་རོགས།',
+'tog-watchlisthidebots' => 'རང་འགུལ་འཕྱུལ་ཆས་ཀྱི་བཟོ་འཅོས་བྱས་པ་རྣམས་ངའི་ལྟ་ཞིབ་ཐོ་ལས་སྦས་རོགས།',
 'tog-watchlisthideminor' => 'རྩོམ་སྒྲིག་ཕལ་བ་རྣམས་ལྟ་ཞིབ་ཐོ་ལས་སྦས་རོགས།',
 'tog-watchlisthideliu' => 'ཐོ་འཛུལ་སྤྱོད་མིའི་རྩོམ་སྒྲིག་རྣམས་ལྟ་ཐོ་ལས་སྦས་རོགས།',
 'tog-ccmeonemails' => 'ངས་གཞན་ལ་བཏང་བའི་གློག་འཕྲིན་གྱི་འདྲ་བཤུས་སྐུར་རོགས།',
 'tog-showhiddencats' => 'སྦས་བའི་དཀར་ཆག་སྟོན་རོགས།',
+'tog-useeditwarning' => 'ངས་རྩོམ་སྒྲིག་ཤོག་ངོས་གང་རུང་ཐོག་བཟོ་འཅོས་རྣམས་ཉར་གཆོག་མ་བྱས་པར་འདོར་ན་ཉེན་བརྡ་གཏོང་རོགས།',
+'tog-prefershttps' => 'རྒྱན་དུ་ནང་འཛུལ་བྱས་བའི་སྐབས་བདེ་འཇགས་འབྲེལ་ལམ་བརྒྱུད་རོགས།',
 
 'underline-always' => 'དུས་རྒྱུན་དུ་',
 'underline-never' => 'གཏན་ནས་མ་བྱེད།',
-'underline-default' => 'རà¾\92ྱསà¼\8bà½\96à¼\8bའà½\91ྲེà½\93à¼\8bà½\94།',
+'underline-default' => 'འཤརà¼\8bà½\86སà¼\8bà½\91à½\84à¼\8bརà¾\92ྱà½\96à¼\8bལà¾\97ོà½\84སà¼\8bརྣà½\98སà¼\8bརà½\84à¼\8bསོརà¼\8bà½\96à½\9eà½\82à¼\8bརོà½\82ས།',
 
 # Font style option in Special:Preferences
-'editfont-style' => 'རྩོམ་སྒྲིག་ཡིག་གཟུགས།',
-'editfont-default' => 'རà¾\92ྱསà¼\8bà½\94à¼\8bའà½\91ྲེà½\93à¼\8bà½\94།',
+'editfont-style' => 'རྩོà½\98à¼\8bསà¾\92ྲིà½\82à¼\8bà½\96à½\9fོà¼\8bའà½\85ོསà¼\8bà½\81ུལà¼\8bà½\82ྱིà¼\8bཡིà½\82à¼\8bà½\82à½\9fུà½\82སà¼\8d',
+'editfont-default' => 'འཤརà¼\8bà½\86སà¼\8bརà½\84à¼\8bསོརà¼\8bà½\96à½\9eà½\82།',
 'editfont-monospace' => 'བར་ཚད་མཉམ་པའི་ཡིག་གཟུགས།',
 'editfont-sansserif' => 'ཡིག་གཟུགས་རྭ་མེད།',
 'editfont-serif' => 'ཡིག་གཟུགས་རྭ་ཅན།',
@@ -118,6 +124,18 @@ $messages = array(
 'oct' => 'ཟླ་བཅུ་བ།',
 'nov' => 'ཟླ་བཅུ་གཅིག་པ།',
 'dec' => 'ཟླ་བཅུ་གཉིས་པ།',
+'january-date' => 'ཟླ་བ་དང་པོ། $1',
+'february-date' => 'ཟླ་བ་གཉིས་པ། $1',
+'march-date' => 'ཟླ་བ་གསུམ་པ། $1',
+'april-date' => 'ཟླ་བ་བཞི་པ། $1',
+'may-date' => 'ཟླ་བ་ལྔ་པ། $1',
+'june-date' => 'ཟླ་བ་དྲུག་པ། $1',
+'july-date' => 'ཟླ་བ་བདུན་པ། $1',
+'august-date' => 'ཟླ་བ་བརྒྱད་པ། $1',
+'september-date' => 'ཟླ་བ་དགུ་པ། $1',
+'october-date' => 'ཟླ་བ་བཅུ་པ། $1',
+'november-date' => 'ཟླ་བ་བཅུ་གཅིག་པ། $1',
+'december-date' => 'ཟླ་བ་བཅུ་གཉིས་པ། $1',
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:|སྡེ་ཚན་|སྡེ་ཚན་ $1}}',
@@ -127,15 +145,24 @@ $messages = array(
 'category-empty' => '<em> སྡེ་ཚན་འདིའི་ནང་དུ་བར་སྐབས་སུ་ཤོག་ངོས་སམ་བརྙན་རིས་མི་འདུག། </em>',
 'hidden-categories' => '|སྦས་བའི་སྡེ་ཚན།|སྦས་བའི་སྡེ་ཚན།}}{{PLURAL:$1',
 'hidden-category-category' => 'སྦས་བའི་སྡེ་ཚན།',
+'category-subcat-count' => '{{PLURAL:$2|སྡེ་ཙན་འདི་ནང་ཁྱོན་སྡོམས་པས་ $2 ནས་ གཤམ་གྱི་བྱེ་བྲག་སྡེ་ཚན།{{PLURAL:$1|subcategory|$1 subcategories}}ཙམ་འདུག།}}',
 'category-subcat-count-limited' => 'སྡེ་ཚན་འདིར་གཤམ་གྱི་བྱེ་བྲག་སྡེ་ཚན་{{PLURAL:$1|subcategory|$1 subcategories}}ཡོད།',
 'category-article-count' => '{{PLURAL:$2|སྡེ་ཚན་འདིར་གཤམ་གྱི་ཤོག་ངོས་ཁོ་ན་བསྡུས་ཡོད། |The following {{PLURAL:$1|page is|$1 pages are}} in this category, out of $2 total.}}',
+'category-article-count-limited' => 'གཤམ་གྱི་{{PLURAL:$1|ཤོག་ངོས་འདི་|$1 ཤོག་ངོས་རྣམས་}}ད་གནས་སྡེ་ཚན་འདི་ནང་ཡོད།',
+'category-file-count' => '{{PLURAL:$2|སྡེ་ཚན་འདི་ནང་གཤམ་གྱི་ཡིག་ཆ་ཁོ་ན་ཡོད།|གཤམ་གྱི་ {{PLURAL:$1|ཡིག་ཆ་འདི་|$1 ཡིག་ཆ་རྣམས་}} སྡེ་ཚན་འདི་ནང་གི་,ཁྱོན་བསྡོམས་གྱི་ $2 ནས་ཡིན།}}',
+'category-file-count-limited' => 'གཤམ་གྱི་{{PLURAL:$1|ཡིག་ཆ་འདི་|$1ཡིག་ཆ་རྣམས་}}ད་གནས་སྡེ་ཚན་འདི་ནང་ཡོད།',
+'listingcontinuesabbrev' => 'མུ་འཐུད།',
+'index-category' => 'དཀར་ཆག་ཅན་གྱི་ཤོག་ངོས།',
+'noindex-category' => 'དཀར་ཆག་མེད་པའི་ཤོག་ངོས།',
+'broken-file-category' => 'ཡིག་ཆའི་སྦྲེལ་མཐུད་འབོར་བརླག་སོང་བའི་ཤོག་ངོས།',
 
 'about' => 'སྐོར།',
 'article' => 'ནང་དོན་ཤོག་ངོས།',
 'newwindow' => '(སྒེའུ་ཁུང་གསར་བར་ཕྱེ་བ།)',
 'cancel' => 'རྩིས་མེད།',
 'moredotdotdot' => 'དེ་ལས་མང་བ་་་',
-'mypage' => 'ངའི་ཤོག་ངོས།',
+'morenotlisted' => 'ཐོ་གཞུང་འདི་ཆ་ཚང་མེད།',
+'mypage' => 'ཤོག་ངོས།',
 'mytalk' => 'གཏམ་གླེང།',
 'anontalk' => 'IP གནས་ཡུལ་འདི་ལ་གླེང་མོལ།',
 'navigation' => 'ཕྱོགས་ཁྲིད།',
@@ -143,7 +170,8 @@ $messages = array(
 
 # Cologne Blue skin
 'qbfind' => 'འཚོལ་བ།',
-'qbedit' => 'རྩོམ་སྒྲིག',
+'qbbrowse' => 'བཤེར་འཚོལ།',
+'qbedit' => 'བཟོ་འཅོས།',
 'qbpageoptions' => 'ཤོག་ངོས་འདི།',
 'qbmyoptions' => 'ངའི་ཤོག་ངོས།',
 'faq' => 'རྒྱུན་ལྡན་དྲི་བ།',
@@ -154,7 +182,7 @@ $messages = array(
 'vector-action-delete' => 'སུབས།',
 'vector-action-move' => 'སྤོར་བ།',
 'vector-action-protect' => 'འགོག་སྲུང།',
-'vector-action-undelete' => 'à½\96སུà½\96སà¼\8bà½\94à¼\8bà½\82སོà¼\8bà½\96à¼\8d',
+'vector-action-undelete' => 'à½\98ིà¼\8bà½\96སུà½\96སà¼\8b',
 'vector-action-unprotect' => 'སྲུང་སྐྱོབ་གློད་པ།',
 'vector-view-create' => 'གསར་བཟོ།',
 'vector-view-edit' => 'རྩོམ་སྒྲིག',
@@ -165,6 +193,7 @@ $messages = array(
 'namespaces' => 'མིང་གནས།',
 'variants' => 'འགྱུར་ཚད།',
 
+'navigation-heading' => 'ཕྱོགས་ཁྲིད་འདེམས་བྱང།',
 'errorpagetitle' => 'ནོར་འཁྲུལ།',
 'returnto' => '$1 ལ་བསྐྱར་ལོག་བྱེད་པ།',
 'tagline' => 'ཡོང་ཁུངས་{{SITENAME}}',
@@ -186,7 +215,8 @@ $messages = array(
 'create-this-page' => 'ཤོག་ངོས་འདི་སྐྲུན་པ།',
 'delete' => 'སུབས།',
 'deletethispage' => 'ཤོག་ངོས་འདི་འདོར་བ།',
-'undelete_short' => '{{PLURAL:$1|one edit|$1edits}} མ་འདོར་ཞིག',
+'undeletethispage' => 'ཤོག་ངོས་འདི་མི་སུབ་རོགས།',
+'undelete_short' => '{{PLURAL:$1|བཟོ་འཅོས་གཅིག་|བཟོ་འཅོས་ $1}}མ་བསུབ་རོགས།',
 'viewdeleted_short' => '{{བསུབས་པའི་རྩོམ་སྒྲིག PLURAL:$1|བསུབས་པའི་རྩོམ་སྒྲིག $1}}ལ་ལྟ་བ།',
 'protect' => 'འགོག་སྲུང།',
 'protect_change' => 'སྒྱུར་བཅོས།',
@@ -215,16 +245,21 @@ $messages = array(
 'redirectedfrom' => '$1 ནས་ཁ་ཕྱོགས་བསྐྱར་དུ་བཟོས་པ།',
 'redirectpagesub' => 'རིམ་འགྲེམ་ཤོག་ངོས།',
 'lastmodifiedat' => 'ཤོག་ངོས་འདི་ཡི་བཟོ་བཅོས་མཐའ་མ་$1 ཀྱི་ $2 ལ་རེད།',
+'viewcount' => 'ཤོགངོས་འདི་{{PLURAL:$1|ཐེངས་གཅིག་|ཐེངས་ $1}}བལྟས་འདུག།',
 'protectedpage' => 'སྲུང་སྐྱོབ་བྱས་པའི་ཤོག་ངོས།',
 'jumpto' => 'གནས་སྤོ།',
 'jumptonavigation' => 'ཕྱོགས་ཁྲིད།',
 'jumptosearch' => 'འཚོལ།',
+'view-pool-error' => 'དགོངས་པ་མ་ཚོམས་རོགས། སྤྱོད་མི་མང་དག་ཞིག་གི་ཤོག་ངོས་འདིར་གཟིགས་ཞིང་འདུག་པས། གནས་སྐབས་རིང་ཞབས་ཞུ་འཕྲུལ་ཆས་ཐེག་བརྒལ་བྱས་འདུག། 
+ཤོག་ངོས་འདིར་བསྐྱར་དུ་མ་གཟིགས་གོང་ཡུད་ཙམ་རིང་སྒུག་རོགས་གནང། $1',
+'pool-timeout' => 'ཟྭ་རྒྱག་སྒུག་ཡུན་གྱི་དུས་ཚོད་རྫོགས་སོང།',
+'pool-queuefull' => 'སྤྱི་པའི་ཐེབས་རྩའི་བསྟར་པ་ཁེངས་འདུག།',
 'pool-errorunknown' => 'ངོས་མ་ཟིན་པའི་ནོར་འཁྲུལ།',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).
 'aboutsite' => '{{SITENAME}}ཡི་སྐོར།',
 'aboutpage' => 'Project:སྐོར།',
-'copyright' => 'à½\91ྲà¼\8bà½\96འིà¼\8bà½\93à½\84à¼\8bà½\91ོà½\93à¼\8b$1སྟེང་དུ་ཡོད།',
+'copyright' => 'à½\91ེà¼\8bà½\98ིà½\93à¼\8bà½\82ྱིà¼\8bà½\98à½\86à½\93à¼\8bའà½\82ྲེལà¼\8bཡོà½\91à¼\8bà½\93à¼\8bà½\98à¼\8bà½\82à½\8fོà½\82སà¼\8d à½\91ྲà¼\8bà½\96འིà¼\8bà½\93à½\84à¼\8bà½\91ོà½\93à¼\8b $1 སྟེང་དུ་ཡོད།',
 'copyrightpage' => '{{ns:project}}:པར་དབང་།',
 'currentevents' => 'ད་ལྟའི་དོན་གནད།',
 'currentevents-url' => 'Project:ད་ལྟའི་དོན་གནད།',
@@ -236,11 +271,15 @@ $messages = array(
 'mainpage-description' => 'གཙོ་གནད་ཤོག་ངོས།',
 'policy-url' => 'Project: སྒྲིག་གཞི།',
 'portal' => 'ཁོངས་མི་གཞུང་སྒོ།',
+'portal-url' => 'Project:ཁོངས་མི་འདུ་རའི་གཞུང་སྒོ་',
 'privacy' => 'གསང་དོན་གན་རྒྱ།',
 'privacypage' => 'Project: གསང་དོན་གན་རྒྱ།',
 
 'badaccess' => 'ཆོག་ཆན་ལ་ནོར་འཁྲུལ།',
 
+'versionrequired' => 'ཝེ་ཁེ་བརྒྱུད་ལམ་གྱི་འགྱུར།  MediaWiki Version $1 དེ་དགོས་འདུག།',
+'versionrequiredtext' => 'ཤོག་ངོས་འདི་བེད་སྤྱོད་པར་ཝེ་ཁེ་བརྒྱུད་ལམ་གྱི་འགྱུར་ $1 འདི་དགོས། [[Special:Version|version page]] འདིར་གཟིགས་རོགས།',
+
 'ok' => 'འགྲིག',
 'retrievedfrom' => '"$1"ལས་སླར་རྙེད་སོང།',
 'youhavenewmessages' => 'ཁྱེད་ལ་འཕྲིན་གསར་$1($2)ཡོད།',
@@ -255,16 +294,22 @@ $messages = array(
 'showtoc' => 'སྟོན།',
 'hidetoc' => 'སྦས།',
 'collapsible-collapse' => 'རྡིབ་སྐྱོན།',
-'viewdeleted' => ' $1 ལ་ལྟའམ།',
+'collapsible-expand' => 'རྒྱ་སྐྱེད།',
+'thisisdeleted' => '$1 ལ་ལྟ་བའམ་རང་ལོགས་བྱེད་རོགས།',
+'viewdeleted' => ' $1 ལ་ལྟ་དགོས་སམ།',
+'feedlinks' => 'འདྲན་ཆས། :',
 'site-rss-feed' => '$1 ཡི་RSS འབྱུང་ཁུངས།',
 'site-atom-feed' => '$1 ཡི་ཆ་ཤས་ཡ་ལན།',
 'page-rss-feed' => '$1 ཡི་RSS འབྱུང་ཁུངས།',
 'page-atom-feed' => '$1 ཡི་Atom འབྱུང་ཁུངས།',
 'red-link-title' => '$1 (ཤོག་ངོས་མེད་པ།)',
+'sort-descending' => 'མར་རིམ་སྒྲིགས་',
+'sort-ascending' => 'ཡར་རིམ་སྒྲིགས།',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
 'nstab-main' => 'ཤོག་ངོས།',
 'nstab-user' => 'སྤྱོད་མིའི་ཤོག་ངོས།',
+'nstab-media' => 'འཕྲིན་ལམ་ཤོག་ངོས།',
 'nstab-special' => 'ཆེད་ལས་ཤོག་ངོས།',
 'nstab-project' => 'ལས་འཆར་ཤོག་ངོས།',
 'nstab-image' => 'ཡིག་ཆ།',
@@ -286,8 +331,17 @@ $messages = array(
 'internalerror' => 'ནང་ལོག་ནོར་སྐྱོན།',
 'internalerror_info' => 'ནང་ལོགས་ནོར་སྐྱོན། $1',
 'filecopyerror' => '"$1" "$2"ལ་འདྲ་བཤུ་བྱེད་མ་ཐུབ།',
+'filerenameerror' => '"$1" ནས་ "$2" བར་མིང་བརྗེ་སྒྱུར་ཐུབ་མ་སོང།',
 'filedeleteerror' => '"$1"ཟེར་བ་སུབ་མ་ཐུབ།',
-'filenotfound' => '"$1"ཟེར་བའི་ཡིག་ཆ་མ་རྙེད་པ།',
+'directorycreateerror' => 'དཀར་ཆག་ "$1" འདི་བཟོ་ཐུབ་མ་སོང།',
+'filenotfound' => '"$1" ཟེར་བའི་ཡིག་ཆ་རྙེད་ཀྱི་མིན་འདུག།',
+'fileexistserror' => 'ཡིག་ཆ་ "$1" འདི་འབྲི་ཐུབ་ཀྱིན་མི་འདུག། ཡིག་ཆ་འདི་བཞིན་འདི་སྔ་ནས་འདུག།',
+'unexpected' => 'ཡོང་མི་སྲིད་པའི་ཁྱད་ཆོས། : "$1"="$2"',
+'formerror' => 'ནོར་འཁྲུལ།:འགེངས་ཤོག་འབུལ་ཐུབ་མ་སོང།',
+'badarticleerror' => 'ཤོག་ངོས་འདི་ཐོག་ལག་བསྟར་བྱེད་ཐུབ་ཀྱི་མ་རེད།',
+'cannotdelete' => 'ཤོག་ངོས་འམ་ཡིག་ཆ་ "$1" འདི་སུབས་ཐུབ་མ་ཀྱི་མིན་འདུག། ཕལ་ཆེར་གཞན་ཞིག་གི་སུབས་ཚར་འདུག།',
+'cannotdelete-title' => 'ཤོག་ངོས་ "$1" འདི་སུབས་ཐུབ་མ་སོང།',
+'delete-hook-aborted' => 'འབྲི་སུབས་འདི་བཀག་འགོག་བྱས་སོང། རྒྱུ་རྐྱེན་བྲིས་མིན་འདུག།',
 'badtitle' => 'ཁ་བྱང་སྐྱོན་ཅན།',
 'viewsource' => 'ཁོངས་ལ་ལྟ་བ།',
 'actionthrottled' => 'བྱ་འགུལ་ཁེགས་སོང་།',
@@ -314,10 +368,10 @@ $messages = array(
 'gotaccount' => '$1 སྔོན་ཚུད་ནས་རྩིས་ཁྲ་ཡོད་དམ།',
 'gotaccountlink' => 'ནང་འཛུལ།',
 'userlogin-resetlink' => 'ཁྱེད་ཀྱི་ནང་འཛུལ་ཀྱི་ཞིབ་ཕྲའི་གནད་དོན་བརྗེད་འདུག་གམ།',
-'createaccountmail' => 'à½\82ློà½\82à¼\8bའà½\95ྲིà½\93à¼\8bསྤྱà½\91à¼\8bà½\91ེ།',
+'createaccountmail' => 'སà¾\90à½\96སà¼\8bའà½\95ྲལà¼\8bརà½\84à¼\8bà½\98ོསà¼\8bà½\82ྱིà¼\8bà½\82སà½\84à¼\8bà½\96འིà¼\8bཨà½\84à¼\8bà½\82ྲà½\84སà¼\8bà½\96ེà½\91à¼\8bསྤྱà½\91à¼\8bà½\94à¼\8bà½\91à½\84à¼\8d à½£à¾·à½\93à¼\8bà½\91ུà¼\8bà½\82ློà½\82à¼\8bའà½\95ྲིà½\93à¼\8bà½\81à¼\8bà½\96ྱà½\84à¼\8bà½\84ེསà¼\8bà½\82à½\8fà½\93à¼\8bà½\9eིà½\82à¼\8bལà¼\8bà½\96སà¾\90ུརà¼\8bརོà½\82ས།',
 'createaccountreason' => 'རྒྱུ་མཚན།',
 'badretype' => 'ལམ་ཡིག་གང་བཅུག་པ་ཐོ་ཐུག་མ་བྱུང་།',
-'userexists' => 'à½\98ིà½\84à¼\8bའà½\91ིà¼\8bà½\96ེà½\91à¼\8bསྤྱོà½\91à¼\8bà½\96ྱསà¼\8bà½\9fིà½\93à¼\8bà½\94སà¼\8bà½\98ིà½\84à¼\8bà½\82à½\9eà½\93à¼\8bà½\9eིà½\82à¼\8bà½\82à½\91à½\98་རོགས།',
+'userexists' => 'སྤྱོà½\91à¼\8bà½\98ིà½\84à¼\8bའà½\91ིà¼\8bསà¾\94ོà½\93à¼\8bà½\9aུà½\91à¼\8bà½\93སà¼\8bà½\96ེà½\91à¼\8bསྤྱོà½\91à¼\8bà½\96ྱསà¼\8bà½\9fིà½\93à¼\8bའà½\91ུà½\82à¼\8bà½\94སà¼\8d à½\98ིà½\84à¼\8bà½\82à½\9eà½\93à¼\8bà½\9eིà½\82à¼\8bà½\82à½\91à½\98à¼\8bà½\82à½\93à½\84་རོགས།',
 'loginerror' => 'ནང་འཛུལ་ནོར་སྐྱོན།',
 'loginsuccesstitle' => 'ནང་འཛུལ་བདེ་བར་གྲུབ།',
 'nosuchusershort' => 'སྤྱོད་མི་"$1"ཟེར་བ་མི་འདུག དག་ཆར་བསྐྱར་ཞིབ་བྱོས།',
@@ -393,6 +447,10 @@ $messages = array(
 'loginreqpagetext' => 'ཤོག་ངོས་གཞན་རྣམས་ལྟ་བར་ངེས་པར་དུ་$1བྱ་དགོས།',
 'accmailtitle' => 'ལམ་ཡིག་བཏང་ཟིན།',
 'newarticle' => '(གསར་བ)',
+'noarticletext' => 'ཤོག་ངོས་འདི་ནང་ད་གནས་ཡིག་གེ་མིན་འདུག།
+ཁྱེད་ཀྱིས་ཤོགངོས་གཞན་ཁག་ནང་ [[Special:Search/{{PAGENAME}}|ཤོག་ངོས་འདིའི་འགོ་བརྗོད་འཚོལ་རོགས།]] <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} དེ་དང་འབྲེལ་བའི་དོ་ཟླའི་ཐོར་འཚོལ་རོགས།],',
+'noarticletext-nopermission' => 'ཤོག་ངོས་འདི་ནང་ད་གནས་ཡི་གེ་མིན་འདུག།
+ཁྱེད་ཀྱིས་ཤོགངོས་གཞན་ཁག་ནང་ [[Special:Search/{{PAGENAME}}|ཤོག་ངོས་འདིའི་འགོ་བརྗོད་འཚོལ་རོགས།]] དེ་མིན་ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} དེ་དང་འབྲེལ་བའི་དོ་ཟླའི་ཐོར་འཚོལ་རོགས།]</span> ཡིན་ནའང་ཁྱེད་ལ་ཤོག་ངོས་འདི་གསར་སྐྲུན་བྱེད་པའི་ཆོག་མཆན་མིན་འདུག།',
 'previewnote' => '"འདི་ནི་སྔོན་ལྟ་ཙམ་ཡིན་པ་ཡིད་ལ་འཇགས་རོགས། "ཁྱེད་ཀྱི་བཟོ་བཅོས་ད་དུང་ཉར་ཚགས་བྱས་མི་འདུག',
 'editing' => '$1རྩོམ་སྒྲིག་བྱེད་བཞིན་པ།',
 'editingsection' => ' $1 (སྡེ་ཚན) ལ་རྩོམ་སྒྲིག་བྱེད་བཞིན་པ།',
@@ -405,6 +463,10 @@ $messages = array(
 'recreate-moveddeleted-warn' => "'''ཉེན་བརྡ་:རང་གིས་སུབ་ཚར་བའི་ཤོག་ལེ་ཞིག་བསྐྱར་བཟོ་བྱེད་ཀྱི་འདུག་ '''
 ཁྱེད་རང་གལ་སྲིད་མུ་མཐུད་ཤོག་ལེ་འདི་བཟོ་ཅོས་བྱེད་འདོད་ན་སྟབས་བདེ་ཞིག་ལ་ང་ཚོས་སུབ་བཟིན་པའི་ཤོག་ལེ་འདིར་ཉར་ཡོད།",
 
+# Parser/template warnings
+'post-expand-template-inclusion-warning' => '<strong> ཉེན་བརྡ།</strong> དཔེ་དཔང་གི་ཚད་གཞི་ཧ་ཅང་ཆེན་པོ་འདུག། དཔེ་དཔང་ཁ་ཅིག་ཚུད་ཐུབ་ཀྱི་མ་རེད།',
+'post-expand-template-inclusion-category' => 'དཔེ་དཔང་གི་ཚད་གཞི་བརྒལ་བའི་ཤོག་ངོས།',
+
 # History pages
 'viewpagelogs' => 'ཤོག་ངོས་འདིའི་ཉིན་ཐོ་ལ་ལྟ་བ།',
 'currentrev-asof' => 'མཐའ་འཇུག་ཀྱི་ཞིབ་བཤེར། $1',
@@ -429,7 +491,7 @@ $messages = array(
 'rev-showdeleted' => 'སྟོན།',
 'revdelete-show-file-submit' => 'ཡིན།',
 'revdelete-radio-same' => 'བཟོ་བཅོས་མ་བྱེད།',
-'revdelete-radio-set' => 'ཡིà½\93།',
+'revdelete-radio-set' => 'à½\98à½\84ོà½\93à¼\8bà½\98ེà½\91à¼\8bà½\80ྱི།',
 'revdel-restore' => 'བཅོས་སུ་རུང་བ།',
 'pagehist' => 'ཤོག་ངོས་ལོ་རྒྱུས།',
 'revdelete-reasonotherlist' => 'རྒྱུ་མཚན་གཞན་པ།',
@@ -443,6 +505,7 @@ $messages = array(
 
 # Diffs
 'lineno' => 'ཐིག་ཕྲེང་$1:',
+'compareselectedversions' => 'འདེམས་བཞིན་པའི་བཟོ་འཅོས་དཔར་གཞིའི་ཁྱད་པར་སྟོན།',
 'editundo' => 'ཕྱིར་འཐེན།',
 
 # Search results
@@ -451,17 +514,21 @@ $messages = array(
 'notextmatches' => 'ཤོག་ངོས་ཡིག་འབྲུ་མཚུངས་པ་མི་འདུག',
 'prevn' => 'སྔོན་མ་{{PLURAL:$1|$1}}',
 'nextn' => 'རྗེས་མ་{{PLURAL:$1|$1}}',
+'prevn-title' => 'དེ་སྔོན་ $1{{PLURAL:$1|གྲུབ་འབྲས།}}',
+'nextn-title' => 'དེ་རྗེས་ཀྱི་ $1{{PLURAL:$1|གྲུབ་འབྲས།}}',
 'shown-title' => 'མིག་སྔར་སྟོན་པ། $1{{PLURAL:$1|གྲུབ་འབྲས།}}ཤོག་ངོས་ལྟར།',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3)ལ་ལྟ་བ།',
 'searchmenu-new' => 'ཝེ་ཁི་སྟེང་ལ་ <strong>ཤོག་ངོས་གསར་པ་</strong> "[[:$1]]" བཟོས། {{PLURAL:$2|0=|ཁྱེད་ཀྱི་འཚོལ་ཞིབ་བྱས་པའི་ཤོག་ངོས་རྣམས་ལ་ཡང་གཟིགས་རོགས།.|མ་ཟད་འཚོལ་ཞིབ་བྱས་པའི་གྲུབ་འབྲས་གཞན་རྣམས་ལ་ཡང་གཟིགས་རོགས།}}',
 'searchprofile-articles' => 'ནང་དོན་ཤོག་ངོས།',
 'searchprofile-project' => 'རོགས་རམ་དང་འཆར་གཞིའི་ཤོག་ངོས་',
+'searchprofile-images' => 'སྨྱན་མང་བརྒྱུད་ལམ།',
 'searchprofile-everything' => 'ཚང་མ་',
 'searchprofile-advanced' => 'མཐོ་རིམ་',
 'searchprofile-articles-tooltip' => '$1ནང་དུ་འཚོལ་བ།',
 'searchprofile-project-tooltip' => '$1ནང་དུ་འཚོལ་བ།',
 'searchprofile-images-tooltip' => 'ཡིག་ཆ་འཚོལ་བ།',
 'searchprofile-everything-tooltip' => 'བརྗོད་དོན་ཚང་མ་འཚོལ་གཞིབ་བྱེད་(གྲོས་མེས་ཤོག་ངོས་ཡང་འཚུད་པ་)',
+'searchprofile-advanced-tooltip' => 'རང་སྒྲུབ་མིང་བར་ནང་འཚོལ་རོགས།',
 'search-result-size' => '$1({{PLURAL:$2|1 ཚིག། |$2 ཚིག།}})',
 'search-redirect' => '($1རིམ་འགྲེམ།)',
 'search-section' => '(ཚན་པ $1)',
@@ -472,6 +539,7 @@ $messages = array(
 'search-relatedarticle' => 'འབྲེལ་ཡོད།',
 'searchrelated' => 'འབྲེལ་ཡོད།',
 'searchall' => 'ཚང་མ།',
+'showingresultsheader' => '{{PLURAL:$5|གྲུབ་འབྲས་ <strong>$1</strong> ཡི་<strong>$3</strong>གྲབ་འབྲས། <strong>$1 - $2</strong> ཡི་ <strong>$3</strong>}} ཆེད་དུ་ <strong>$4</strong>',
 'search-nonefound' => 'ཁྱེད་ཀྱི་འདྲི་ཞིབ་དང་མཐུན་པའི་ལན་མི་འདུག་',
 'powersearch-legend' => 'ཞིབ་ཏུ་འཚོལ་བ།',
 'powersearch-ns' => 'མིང་གནས་ནང་འཚོལ་བ།',
@@ -486,7 +554,7 @@ $messages = array(
 'prefs-personal' => 'སྤྱོད་མིའི་སྤྱི་ཁོག',
 'prefs-rc' => 'ཉེ་བའི་བཟོ་བཅོས།',
 'prefs-watchlist' => 'མཉམ་འཇོག་ཐོ།',
-'prefs-watchlist-days-max' => 'Maximum $1 {{PLURAL:$1|day|days}}',
+'prefs-watchlist-days-max' => 'མང་མཐར་ཡང་ $1 {{PLURAL:$1|ཉིན།|ཉིན།}}',
 'prefs-watchlist-edits-max' => 'མང་ཚད་ཨང་གྲངས། ༡༠༠༠',
 'prefs-resetpass' => 'ལམ་ཡིག་བརྗེ་བ།',
 'prefs-changeemail' => 'དྲ་འཕྲིན་བརྗེ་བ།',
@@ -497,14 +565,14 @@ $messages = array(
 'stub-threshold-disabled' => 'ནུས་མེད་དུ་བཟོས་ཟིན།',
 'timezoneregion-africa' => 'ཨ་ཧྥི་རི་ཀ',
 'youremail' => 'གློག་འཕྲིན།:',
-'username' => 'དྲ་མིང་།:',
-'uid' => 'ནང་འཛུལ་ཐོ་མིང་།',
+'username' => '{{GENDER:$1|དྲ་མིང་།}}:',
+'uid' => '{{GENDER:$1|སྤྱོད་མིའི་}}ནང་འཛུལ་ཐོ་མིང་།:',
 'yourrealname' => 'དངོས་མིང་།',
 'yourlanguage' => 'སྐད་རིགས།',
 'yournick' => 'མིང་རྟགས་སོ་མ།',
-'yourgender' => 'à½\95ོà¼\8bà½\98ོ།',
-'gender-male' => 'à½\95ོ།',
-'gender-female' => 'མོ།',
+'yourgender' => 'à½\81ྱེà½\91à¼\8bལà¼\8bà½\82à½\84à¼\8bའà½\91ྲà¼\8bà½\96ྱསà¼\8bà½\93སà¼\8bའà½\96ོà½\91à¼\8bà½\91à½\82ོསà¼\8bསà½\98།',
+'gender-male' => 'à½\81ོà¼\8bརà½\84à¼\8bà½\82ིསà¼\8bà½\9dེà¼\8bà½\81ེà¼\8bརྩོà½\98à¼\8bསà¾\92ྲིà½\82à¼\8bà½\96ྱསà¼\8bསོà½\84།',
+'gender-female' => 'à½\98ོà¼\8bརà½\84à¼\8bà½\82ིསà¼\8bà½\9dེà¼\8bà½\81ེà¼\8bཤོà½\82à¼\8bà½\84ོསà¼\8bà½\90ོà½\82à¼\8bརྩོà½\98à¼\8bསà¾\92ྲིà½\82à¼\8bà½\96ྱསà¼\8bསོà½\84à¼\8d',
 'email' => 'དྲ་འཕྲིན།',
 'prefs-help-email' => 'གློག་འཕྲིན་ཁ་བྱང་ནི་རང་མོས་ཡིན། ཡིན་ན་འང་གལ་སྲིད་ཁྱེད་ཀྱི་གསང་བའི་ཨང་གྲངས་འརྗེད་པ་སོགས་བྱུང་ཚེ། གསང་བའི་ཨང་བསྐྱར་སྒྲིག་སྐབས་ངེས་པར་དུ་དགོས།',
 'prefs-help-email-others' => 'ཁྱེད་ཀྱི་ཐད་ཀར་གློག་འཕྲིན་འམ་ཡང་ན་འགྲོ་གླེང་ཤོག་ངོས་བརྒྱུད་སྤྱོད་མི་གཞན་རྣམས་ཀྱི་ཁྱེད་ལ་འབྲེལ་བ་བྱེད་ཐུབ། ཁྱེད་རང་གི་གློག་འཕྲིན་ཁ་བྱང་སྤྱོད་མི་གཞན་གྱི་འབྲེལ་བ་བྱེད་སྐབས་གསང་གཏོལ་བྱེད་མི་སྲིད།',
@@ -547,8 +615,8 @@ $messages = array(
 'action-undelete' => 'ཤོག་ངོས་འདི་བསུབས་ཟིན་གསོ་བ།',
 'action-block' => 'སྤྱོད་མི་འདི་རྩོམ་སྒྲིག་ལ་ཁོག་ཅིག',
 'action-protect' => 'ཤོག་ངོས་འདིའི་སྲུང་སྐྱོབ་རིམ་པ་བསྒྱུར་བཅོས་གཏོང་བ།',
-'action-import' => 'ཤོà½\82à¼\8bà½\84ོསà¼\8bའà½\91ིà¼\8bà½\9dེà¼\8bà½\81ེà¼\8bà½\82à½\9eà½\93à¼\8bà½\93སà¼\8bà½\93à½\84à¼\8bའà½\91ྲེà½\93à¼\8bà½\96ྱེà½\91à¼\8bà½\94།',
-'action-importupload' => 'ཤོà½\82à¼\8bà½\84ོསà¼\8bའà½\91ིà¼\8bཡིà½\82à¼\8bà½\86à¼\8bཡརà¼\8bའà½\87ུà½\82à¼\8bལསà¼\8bà½\93à½\84à¼\8bའà½\91ྲེà½\93à¼\8bà½\96ྱེà½\91à¼\8bà½\94།',
+'action-import' => 'à½\9dེà¼\8bà½\81ེà¼\8bà½\82à½\9eà½\93à¼\8bà½\93སà¼\8bà½\93à½\84à¼\8bའà½\91ྲེà½\93à¼\8bà½\96ྱེà½\91à¼\8bà½\94འིà¼\8bཤོà½\82à¼\8bà½\84ོས།',
+'action-importupload' => 'ཡིà½\82à¼\8bà½\86à¼\8bཡརà¼\8bའà½\87ུà½\82à¼\8bལསà¼\8bà½\93à½\84à¼\8bའà½\91ྲེà½\93à¼\8bà½\96ྱེà½\91à¼\8bà½\94འིà¼\8bཤོà½\82à¼\8bà½\84ོས།',
 'action-unwatchedpages' => 'མ་བལྟས་ཤོག་ངོས་ཀྱི་ཐོ་ལ་ལྟ་བ།',
 'action-userrights' => 'སྤྱོད་མིའི་ཐོབ་ཐང་ཡོངས་ལ་རྩོམ་སྒྲིག་བྱེད་པ།',
 'action-userrights-interwiki' => 'ཝེ་ཁེ་གཞན་གྱི་སྤྱོད་མི་ཚོའི་སྤྱོད་མིའི་ཐོབ་ཐང་རྩོམ་སྒྲིག་བྱེད་པ།',
@@ -559,8 +627,11 @@ $messages = array(
 'recentchanges-legend' => 'ཉེ་བའི་བཟོ་བཅོས་འདེམས་ཚན།',
 'recentchanges-label-newpage' => 'རྩོམ་སྒྲིག་འདིས་ཤོག་ངོས་གསར་བ་ཞིག་བཟོས་འདུག',
 'recentchanges-label-minor' => 'འདི་ནི་རྩོམ་སྒྲིག་ཕལ་བ་ཞིག་ཡིན།',
+'recentchanges-label-bot' => 'བཟོ་འཅོས་འདི་རང་འགུལ་འཕྲུལ་ཆས་ཀྱིས་བྱས་སོང།',
+'recentchanges-label-unpatrolled' => 'རྩོམ་སྒྲིག་འདི་སྐོར་ཞིབ་བྱེད་རྒྱུ་རེད་འདུག།',
 'rclistfrom' => '$1 ལས་འགོ་བཙུགས་ཏེ་འགྱུར་བཅོས་གསར་བ་སྟོན་ཅིག',
 'rcshowhideminor' => '$1 རྩོམ་སྒྲིག་ཕལ་བ།',
+'rcshowhidebots' => '$1 རང་འགུལ་འཕྲུལ་ཆས།',
 'rcshowhideliu' => '$1 ཐོ་འགོད་སྤྱོད་མི།',
 'rcshowhideanons' => 'མིང་མེད་སྤྱོད་མི $1',
 'rcshowhidemine' => '$1ངའི་རྩོམ་སྒྲིག',
@@ -583,6 +654,7 @@ $messages = array(
 'recentchangeslinked-title' => '"$1" དང་འབྲེལ་བའི་འགྱུར་བཅོས།',
 'recentchangeslinked-summary' => "འདི་ནི་དམིགས་གསལ་ཤོག་ངོས་༼ཡང་ན་དམིགས་གསལ་རྣམ་གྲངས་ཀྱི་ཁོངས་མི་༽དང་འབྲེལ་བའི་ཉེ་བའི་བཟོ་བཅོས་རེད།[[Special:Watchlist|yourwatchlist]] ནང་གི་ཤོག་ངོས་རྣམས་'''ཡིག་གཟུགས་སྦོམ་པོ་'''ཡིན།",
 'recentchangeslinked-page' => 'ཤོག་ངོས་མིང་།',
+'recentchangeslinked-to' => 'ཤོག་ངོས་འདི་ཐོག་གི་བཟོ་འཅོས་རྣམས་ཤོག་ངོས་དེ་དང་འབྲེལ་བའི་འགྱུར་བ་སྟོན་རོགས།',
 
 # Upload
 'upload' => 'ཡིག་ཆ་ཡར་འཇུག',
@@ -607,6 +679,7 @@ $messages = array(
 'uploaddisabled' => 'ཡར་འཇུག་ནུས་མེད་བཟོས་འདུག',
 'watchthisupload' => 'ཡིག་ཆ་འདི་ལ་གཟིགས།',
 
+'license' => 'གན་རྒྱ་ནང་ཞུགས་པ།',
 'license-header' => 'གན་རྒྱ་ནང་ཞུགས་པ།',
 
 # Special:ListFiles
@@ -636,6 +709,8 @@ $messages = array(
 'filehist-missing' => 'ཡིག་ཆ་ཆད་པ།',
 'imagelinks' => 'ཡིག་ཆ་བེད་སྤྱོད་ཁུལ།',
 'linkstoimage' => '{{PLURAL:$1|pagelinks|$1pagelink}} འདི་ལ་སྦྲེལ་ཡོད།',
+'sharedupload-desc-here' => 'ཡིག་ཆ་འདི་ནས་$1 རེད་འདུག། ལས་འཆར་གཞན་ཁག་ནང་བེད་སྤྱོད་ཡོད་ངེས།
+[$2 འགྲེལ་བརྗོད་ཤོག་ངོས་]འདིའི་འགྲེལ་བརྗོད་གཤམ་དུ་འཁོད་ཡོད།',
 'shared-repo-from' => '$1 ནས།',
 
 # File deletion
@@ -688,15 +763,18 @@ $messages = array(
 'allarticles' => 'ཤོག་ངོས་ཆ་ཚང་།',
 'allpagessubmit' => 'སོང་།',
 
+# Special:Categories
+'categories' => 'སྡེ་ཚན།',
+
 # Special:LinkSearch
-'linksearch' => 'ཕྱི་རོལ་སྦྲེལ་མཐུད།',
+'linksearch' => 'à½\95ྱིà¼\8bརོལà¼\8bསྦྲེལà¼\8bà½\98à½\90ུà½\91à¼\8bའà½\9aོལà¼\8bà½\9eིà½\96à¼\8d',
 
 # Special:ListGroupRights
 'listgrouprights-members' => 'ཁོངས་མིའི་ཐོ་ཡིག',
 
 # Email user
 'emailuser' => 'སྤྱོད་མི་འདིར་གློག་འཕྲིན་སྐུར་བ།',
-'emailmessage' => 'སà¾\90à½\91à¼\8bà½\86།',
+'emailmessage' => 'à½\96རྡà¼\8bའà½\95ྲིà½\93།',
 
 # Watchlist
 'watchlist' => 'ལྟ་ཞིབ་ཐོ།',
@@ -740,9 +818,9 @@ $messages = array(
 'protectexpiry' => 'དུས་ཡུན་རྫོགས་ཚད།',
 'protect_expiry_invalid' => 'དུས་ཡུན་རྫོགས་ཚད་ནོར་བ།',
 'protect-default' => 'སྤྱོད་མི་ཡོངས་ལ་ཕྱེ་བ།',
-'protect-fallback' => '"$1" ཆོག་མཆན་དགོས།',
-'protect-level-autoconfirmed' => 'སྤྱོà½\91à¼\8bà½\98ིà¼\8bà½\82སརà¼\8bà½\96à¼\8bà½\91à½\84à¼\8bà½\90ོà¼\8bà½\98ེà½\91à¼\8bརྣà½\98སà¼\8bà½\96à½\80à½\82à¼\8bའà½\82ོà½\82',
-'protect-level-sysop' => 'དོ་དམ་པ་ཁོ་ནར།',
+'protect-fallback' => 'སྤྱོད་མི་ "$1" གྱི་ཆོག་མཆན་ཡོད་པ་ཁོ་ནར་བྱེད་དབང་ཡོད།',
+'protect-level-autoconfirmed' => 'རà½\84à¼\8bའà½\82ུལà¼\8bà½\84ོསà¼\8bའà½\9bིà½\93à¼\8bà½\96ྱསà¼\8bà½\94འིà¼\8bསྤྱོà½\91à¼\8bà½\98ིà¼\8bà½\81ོà¼\8bà½\93རà¼\8bà½\96ྱེà½\91à¼\8bà½\91à½\96à½\84à¼\8bཡོà½\91à¼\8d',
+'protect-level-sysop' => 'à½\91ོà¼\8bà½\91à½\98à¼\8bà½\94à¼\8bà½\81ོà¼\8bà½\93རà¼\8bà½\96ྱེà½\91à¼\8bà½\91à½\96à½\84à¼\8bཡོà½\91à¼\8d',
 'protect-cantedit' => 'ཁྱོད་ལ་ཤོག་ངོས་འདི་རྩོམ་སྒྲིག་གི་ཆོག་མཆན་མེད་པས་ངོས་འདི་ཡི་སྲུང་སྐྱོབ་རིམ་པ་ལ་བཟོ་བཅོས་བྱེད་མི་ཆོག',
 'restriction-type' => 'ཆོག་མཆན།',
 'restriction-level' => 'དམ་བསྒྲགས་ཚད་རིམ།',
@@ -865,6 +943,8 @@ $messages = array(
 'tooltip-save' => 'བཟོ་བཅོས་ཉར་ཚགས་བྱོས།',
 'tooltip-preview' => 'ཉར་ཚགས་ཀྱི་སྔོན་དུ་བཟོ་བཅོས་ལ་བསྐྱར་ཞིབ་གནང་རོགས།',
 'tooltip-diff' => 'གང་ལ་བཟོ་བཅོས་བྱས་པའི་ཡིག་འབྲུ་སྟོན་པ།',
+'tooltip-compareselectedversions' => 'ཤོག་ངོས་འདེམས་བཞིན་བ་གཉིས་ཀྱི་བར་བཟོ་འཅོས་དཔར་གཞིའི་ཁྱད་པར་སྟོན།',
+'tooltip-rollback' => '"རྒྱབ་སྒྲིལ།" ཞེས་པ་འདིས་ཤོག་ངོས་སྟེང་གི་དེ་སྔོན་གི་རྩོམ་སྒྲིག་མཐུན་འགྱུར་རྣམས་མཐེབ་གཞོང་གནོན་ཐེངས་གཅིག་ལ་ཕྱིར་ལྡོག་བྱེད་རྒྱུ་ཡིན།',
 'tooltip-undo' => '"ཕྱིར་འཐེན།" ཞེས་པ་དེས་ཁྱེད་ཀྱི་རྩོམ་སྒྲིག་ཕྱིར་ལྡོག་པ་དང་སྔོན་འཚུད་བལྟ་ཞིབ་ཤོག་ངོས་ཁ་ཕྱེ་རྒྱུ་ཡིན། མཇུག་སྡོམ་ཀྱི་རྒྱུ་རྐྱེན་གླེང་འཇུག་རྒྱུ་ཡིན།',
 'tooltip-summary' => 'ཕྱོགས་བསྡོམས་ཐུང་ངུ་ཞིག་འབྲིས་',
 
@@ -873,11 +953,24 @@ $messages = array(
 'nextdiff' => 'རྩོམ་སྒྲིག་གསར་གྲས། →',
 
 # Media information
+'file-info-size' => '$1 × $2 བརྙན་རྒྱུ།, ཡིག་ཆ་ཆེ་ཆུང།: $3, རྣམ་གཞག།: $4',
 'show-big-image' => 'ཐོག་མའི་ཡིག་ཆ།',
 
 # Special:NewFiles
 'ilsubmit' => 'འཚོལ།',
 
+# Bad image list
+'bad_image_list' => 'གཤམ་གྱི་རྣམ་གཞག་ལྟར་རྗེས་སུ་འབྲང་རོགས།:
+རེའུ་མིག་ཡོད་པ་ཁོ་ན་ཆ་འཇོག་བྱེད་རྒྱ་ཡིན།',
+
+# Metadata
+'metadata' => 'རྒྱུ་གཞི་གྲངས།',
+'metadata-help' => 'ཡིག་ཆ་འདིར་ཆ་འཕྲིན་གཞན་དག་པ་ཁ་ཅིག་འདུག། ཕལ་ཆེར་གྲངས་འཛིན་དཔར་ཆས་འམ་འབེབས་ཆས་ལས་གྲངས་འཛིན་ཡོང་ཆེད་བཟོས་པ་ཡིན། 
+གལ་སྲིད་ཡིག་ཆ་འདིར་འགྱུར་བ་གཏོང་གནང་ན། དེ་སྔོན་གྱི་ལྟར་ཞིབས་ཚག་སྟོན་མི་ཐུབ།',
+'metadata-fields' => 'དཔར་རིས་ཀྱི་ནང་དོན་འདིར་ཡོད་པ་རྣམས་ནང་དོན་ཞིབ་ཕྲའི་སྐབས་སྟོན་རྒྱུ་ཡིན། དེ་མིན་རྣམས་རང་འགུལ་གྱི་འབས་ཞོགས་རྒྱུ་ཡིན།
+* བཟོ་སྐྲུན།
+* དབྱབས་གཟུགས།',
+
 # 'all' in various places, this might be different for inflected languages
 'watchlistall2' => 'ཚང་མ།',
 'namespacesall' => 'ཡོངས་རྫོགས།',
@@ -897,6 +990,9 @@ $messages = array(
 # Special:SpecialPages
 'specialpages' => 'ཆེད་ལས་ཤོག་ངོས།',
 
+# Special:Tags
+'tag-filter' => '[[Special:མཆན་བུ་|མཆན་བུ།]] འདེམས་འཚག།:',
+
 # New logging system
 'rightsnone' => '(སྟོང་པ།)',
 
index d86fcb9..0b81c5f 100644 (file)
@@ -617,7 +617,7 @@ No oblideu de canviar les vostres [[Special:Preferences|preferències de {{SITEN
 'yourname' => "Nom d'usuari",
 'userlogin-yourname' => 'Usuari',
 'userlogin-yourname-ph' => "Introduïu el vostre nom d'usuari",
-'createacct-another-username-ph' => "Introdueix el nom d'usuari",
+'createacct-another-username-ph' => "Introduïu el nom d'usuari",
 'yourpassword' => 'Contrasenya',
 'userlogin-yourpassword' => 'Contrasenya',
 'userlogin-yourpassword-ph' => 'Introduïu la vostra contrasenya',
@@ -654,11 +654,11 @@ No oblideu de canviar les vostres [[Special:Preferences|preferències de {{SITEN
 Feu servir el formulari de sota per iniciar la sessió com un altre usuari.',
 'userlogin-createanother' => 'Crea un altre compte',
 'createacct-join' => 'Introduïu les vostres dades.',
-'createacct-another-join' => 'Introdueix la informació del nou compte a continuació:',
+'createacct-another-join' => 'Introduïu la informació del nou compte a continuació:',
 'createacct-emailrequired' => 'Adreça de correu electrònic',
 'createacct-emailoptional' => 'Adreça de correu electrònic (opcional)',
 'createacct-email-ph' => 'Introduïu la vostra adreça de correu electrònic',
-'createacct-another-email-ph' => 'Introdueix una adreça de correu electrònic',
+'createacct-another-email-ph' => 'Introduïu una adreça de correu electrònic',
 'createaccountmail' => "Utilitza una contrasenya aleatòria temporal i envia-la a l'adreça de correu indicada",
 'createacct-realname' => 'Nom real (opcional)',
 'createaccountreason' => 'Motiu:',
@@ -737,6 +737,9 @@ Espereu $1 abans de tornar-ho a provar.",
 'suspicious-userlogout' => "S'ha denegat la vostra petició per tancar la sessió ja què sembla que va ser enviada per un navegador defectuós o un proxy cau.",
 'createacct-another-realname-tip' => "El nom real és opcional.
 Si decidiu proporcionar-lo, s'utilitzarà per a reconèixer a l'usuari el seu treball.",
+'pt-login' => 'Iniciar sessió',
+'pt-createaccount' => 'Crea un compte',
+'pt-userlogout' => 'Finalitza la sessió',
 
 # Email sending
 'php-mail-error-unknown' => 'Error desconegut en la funció mail() de PHP',
@@ -767,7 +770,7 @@ Per completar l'inici de sessió heu de definir una contrasenya nova a continuac
 'resetpass-temp-password' => 'Contrasenya temporal:',
 'resetpass-abort-generic' => 'Una extensió ha interromput el canvi de contrasenya.',
 'resetpass-expired' => 'La contrasenya ha vençut. Definiu una contrasenya nova per iniciar la sessió.',
-'resetpass-expired-soft' => 'La contrasenya ha vençut i cal restablir-la. Trieu una contrasenya nova ara, o feu clic a cancel·lat per a restablir-la més endavant.',
+'resetpass-expired-soft' => 'La contrasenya ha vençut i cal restablir-la. Trieu una contrasenya nova ara, o feu clic a «{{int:resetpass-submit-cancel}}» per a restablir-la més endavant.',
 
 # Special:PasswordReset
 'passwordreset' => 'Restablir contrasenya',
@@ -1610,14 +1613,26 @@ Ha de tenir com a molt {{PLURAL:$1|un caràcter|$1 caràcters}}.',
 'recentchanges-legend-heading' => "'''Llegenda:'''",
 'recentchanges-legend-newpage' => '(vegeu també la [[Special:NewPages|llista de pàgines noves]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => 'A sota hi ha els canvis des de <b>$2</b> (es mostren fins <b>$1</b>).',
+'rcnotefrom' => 'A sota hi ha els canvis des de <strong>$2</strong> (es mostren fins <strong>$1</strong>).',
 'rclistfrom' => 'Mostra els canvis nous des de $1',
 'rcshowhideminor' => '$1 edicions menors',
+'rcshowhideminor-show' => 'Mostra',
+'rcshowhideminor-hide' => 'Amaga',
 'rcshowhidebots' => '$1 bots',
+'rcshowhidebots-show' => 'Mostra',
+'rcshowhidebots-hide' => 'Amaga',
 'rcshowhideliu' => '$1 usuaris registrats',
+'rcshowhideliu-show' => 'Mostra',
+'rcshowhideliu-hide' => 'Amaga',
 'rcshowhideanons' => '$1 usuaris anònims',
+'rcshowhideanons-show' => 'Mostra',
+'rcshowhideanons-hide' => 'Amaga',
 'rcshowhidepatr' => '$1 edicions supervisades',
+'rcshowhidepatr-show' => 'Mostra',
+'rcshowhidepatr-hide' => 'Amaga',
 'rcshowhidemine' => '$1 edicions pròpies',
+'rcshowhidemine-show' => 'Mostra',
+'rcshowhidemine-hide' => 'Amaga',
 'rclinks' => 'Mostra els darrers $1 canvis en els darrers $2 dies<br />$3',
 'diff' => 'dif',
 'hist' => 'hist',
@@ -1740,6 +1755,7 @@ Si us plau, si encara desitgeu carregar el vostre fitxer, torneu enrera i carreg
 'uploaddisabledtext' => "S'ha inhabilitat la càrrega de fitxers.",
 'php-uploaddisabledtext' => 'La càrrega de fitxer està desactivada al PHP. Comproveu les opcions del fitxer file_uploads.',
 'uploadscripted' => 'Aquest fitxer conté codi HTML o de seqüències que pot ser interpretat equivocadament per un navegador.',
+'uploadscriptednamespace' => 'Aquest fitxer SVG conté un espai de noms "$1" no autoritzat',
 'uploadinvalidxml' => "No s'ha pogut analitzar l'XML del fitxer carregat.",
 'uploadvirus' => 'El fitxer conté un virus! Detalls: $1',
 'uploadjava' => 'El fitxer és un arxiu ZIP que conté un fitxer .class de Java. No està permesa la càrrega de fitxers Java, perquè poden passar per alt les restriccions de seguretat.',
@@ -2551,8 +2567,10 @@ Per més detalls, la última entrada del registre es mostra a continuació:",
 'sp-contributions-blocked-notice-anon' => 'En aquests moments, aquesta adreça IP es troba blocada.
 Per més detalls, la última entrada del registre es mostra a continuació:',
 'sp-contributions-search' => 'Cerca les contribucions',
+'sp-contributions-suppresslog' => "contribucions suprimides de l'usuari",
 'sp-contributions-username' => "Adreça IP o nom d'usuari:",
 'sp-contributions-toponly' => 'Mostra només revisions superiors',
+'sp-contributions-newonly' => 'Mostra només modificacions que són creacions de pàgina',
 'sp-contributions-submit' => 'Cerca',
 
 # What links here
index 1fc077a..21121a2 100644 (file)
@@ -327,7 +327,7 @@ $messages = array(
 'tog-usenewrc' => 'Лелабе дика могӀам керла чу хийцамашна (оьшу JavaScript)',
 'tog-numberheadings' => 'Ша шех хlитто терахь корташна',
 'tog-showtoolbar' => 'Гайта лакхара гӀирсан дакъа нисйеш аттон оц тадар чохь (JavaScript)',
-'tog-editondblclick' => 'Нисйе агӀонаш шозза тӀетаӀийча (JavaScript)',
+'tog-editondblclick' => 'Нисъе агӀонаш шозза тӀетаӀийча (JavaScript)',
 'tog-editsectiononrightclick' => 'Нисде дакъа шозза бакъехьар дахка тӀетаӀийча оцу кортан (JavaScript)',
 'tog-rememberpassword' => 'Даглаца сан дӀаяздар хӀокху браузеран тӀехь (цхьан $1 {{PLURAL:$1|дийнахь}})',
 'tog-watchcreations' => 'ТӀетоха ас кхоьллина агӀонаш тергаме могӀам чу',
@@ -470,7 +470,7 @@ $messages = array(
 # Cologne Blue skin
 'qbfind' => 'Лаха',
 'qbbrowse' => 'Хьажар',
-'qbedit' => 'Нисйé',
+'qbedit' => 'Нисъе',
 'qbpageoptions' => 'Агlо нисйар',
 'qbmyoptions' => 'Хьан нисдарш',
 'faq' => 'СиХХ',
@@ -484,7 +484,7 @@ $messages = array(
 'vector-action-undelete' => 'Меттахlоттадé',
 'vector-action-unprotect' => 'ГӀароллех къаста',
 'vector-view-create' => 'Кхоллар',
-'vector-view-edit' => 'Нисйé',
+'vector-view-edit' => 'Нисъе',
 'vector-view-history' => 'АгӀона хийцамаш',
 'vector-view-view' => 'Éшар',
 'vector-view-viewsource' => 'Билглонашка хьажа',
@@ -508,9 +508,9 @@ $messages = array(
 'permalink' => 'Даиман йолу хьажораг',
 'print' => 'Зорба тоха',
 'view' => 'Хьажа',
-'edit' => 'Нисйé',
+'edit' => 'Нисъе',
 'create' => 'Кхолла',
-'editthispage' => 'Нисйé хlара агlо',
+'editthispage' => 'Нисъе хӀъара агӀо',
 'create-this-page' => 'Кхолла хlара агlо',
 'delete' => 'ДӀаяккха',
 'deletethispage' => 'ДӀаяккха хӀара агӀо',
@@ -594,10 +594,10 @@ $1',
 'newmessageslinkplural' => '{{PLURAL:$1|керла хаам|999=керла хаамаш}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|тӀаьхьара бина хийцам|999=тӀаьхьара бина хийцамаш}}',
 'youhavenewmessagesmulti' => 'Хьуна кхаьчна керла хаам оцу $1',
-'editsection' => 'нисйé',
-'editold' => 'нисйé',
+'editsection' => 'нисъе',
+'editold' => 'нисъе',
 'viewsourceold' => 'хьажа йолуш йолучу коде',
-'editlink' => 'нисйé',
+'editlink' => 'нисъе',
 'viewsourcelink' => 'хьажа йолуш йолучу коде',
 'editsectionhint' => 'Нисде дакъа: $1',
 'toc' => 'Чулацам',
@@ -1361,7 +1361,7 @@ $1",
 'group' => 'Тоба:',
 'group-user' => 'Декъашхой',
 'group-autoconfirmed' => 'Ша тӀелаьцболу декъашхой',
-'group-bot' => 'ШаболÑ\85Ñ\85ой',
+'group-bot' => 'Ð\91оÑ\82аÑ\88',
 'group-sysop' => 'Куьйгалхой',
 'group-bureaucrat' => 'Бюрократаш',
 'group-suppress' => 'Ревизораш',
@@ -1369,14 +1369,14 @@ $1",
 
 'group-user-member' => '{{GENDER:$1|декъашхо}}',
 'group-autoconfirmed-member' => '{{GENDER:$1|шашеха тӀелаьцна декъашхо}}',
-'group-bot-member' => 'шаболххо',
+'group-bot-member' => '{{GENDER:$1|бот}}',
 'group-sysop-member' => '{{GENDER:$1|куьйгалхо}}',
 'group-bureaucrat-member' => '{{GENDER:$1|бюрократхо}}',
 'group-suppress-member' => '{{GENDER:$1|ревизор}}',
 
 'grouppage-user' => '{{ns:project}}:Декъашхой',
 'grouppage-autoconfirmed' => '{{ns:project}}:Бакъонаш йолу декъашхой',
-'grouppage-bot' => '{{ns:project}}:ШаболÑ\85Ñ\85ой',
+'grouppage-bot' => '{{ns:project}}:Ð\91оÑ\82аÑ\88',
 'grouppage-sysop' => '{{ns:project}}:Куьйгалхой',
 'grouppage-bureaucrat' => '{{ns:project}}:Бюрократаш',
 'grouppage-suppress' => '{{ns:project}}:Ревизораш',
@@ -1493,7 +1493,7 @@ $1",
 'recentchanges' => 'Керла нисдарш',
 'recentchanges-legend' => 'Гlирс нисбарна керла нисдарш',
 'recentchanges-summary' => 'Лахахь гайтина хене хьаьжна Википедин агӀонашкахь тӀаьхьара бина хийцамаш',
-'recentchanges-noresult' => 'Билгал йинчу хенахь цӀа хийцамаш бина бац.',
+'recentchanges-noresult' => 'Билгал йинчу хенахь цхьа хийцамаш бина бац.',
 'recentchanges-feed-description' => 'Тергам бе тlаьхьара вики хийцаман хlокху ларца.',
 'recentchanges-label-newpage' => 'Оцу нисдарца кхоллина керла агlо.',
 'recentchanges-label-minor' => 'Хlара нисдинарг къастийна жимо долушсан',
@@ -1506,7 +1506,7 @@ $1",
 'rcshowhideminor' => '$1 кегийра нисдарш',
 'rcshowhideminor-show' => 'Гайта',
 'rcshowhideminor-hide' => 'Къайладаха',
-'rcshowhidebots' => '$1 шабелхалой',
+'rcshowhidebots' => '$1 боташ',
 'rcshowhidebots-show' => 'Гайта',
 'rcshowhidebots-hide' => 'Къайлабаха',
 'rcshowhideliu' => '$1 шайн цӀершца болу декъашхой',
@@ -1736,7 +1736,7 @@ PICT # тайп тайпан
 'unusedtemplates' => 'Лелош доцу кепаш',
 'unusedtemplatestext' => 'Кхузахь дагар йина «{{ns:template}}» цӀерийн меттиган агӀонаш, кхечу агӀонийн юкъа тоьхна йоцу.
 Диц ма делахь хьажа кеп агӀонашкахь лелош юй.',
-'unusedtemplateswlh' => 'кÑ\85ин Ñ\85Ñ\8cажоÑ\80агаÑ\88',
+'unusedtemplateswlh' => 'кхин хьажоргаш',
 
 # Random page
 'randompage' => 'Цахууш нисйелла агӀо',
@@ -1777,7 +1777,7 @@ PICT # тайп тайпан
 
 'brokenredirects' => 'ДIахаьдна долу дIасахьажораш',
 'brokenredirectstext' => 'Лахара дӀасахьажийнарш ю йоцучу агӀонийн тӀе хьажийна:',
-'brokenredirects-edit' => 'нисйé',
+'brokenredirects-edit' => 'нисъе',
 'brokenredirects-delete' => 'дӀаяккха',
 
 'withoutinterwiki' => 'Юкъарвики-хьажорагаш йоцу агӀонаш',
@@ -1916,7 +1916,7 @@ PICT # тайп тайпан
 'activeusers-intro' => 'Лахахь гойтуш бу  {{PLURAL:$1|1=тӀаьхьара $1 динахь|тӀаьхьара $1 деношкахь}} хийцамаш бина декъашхой.',
 'activeusers-count' => '{{PLURAL:$3|1=тӀаьхьарчу $3 динахь|тӀаьхьара $3 деношкахь}} $1 {{PLURAL:$1|1=нисдар|нисдарш}} дина',
 'activeusers-from' => 'Гучé баха декъашхой, болалуш болу тӀера:',
-'activeusers-hidebots' => 'Къайлабаха шабелхалой',
+'activeusers-hidebots' => 'Къайлабаха боташ',
 'activeusers-hidesysops' => 'Къайлабаха куьйгалхой',
 'activeusers-noresult' => 'Декъашхой цакарий.',
 
@@ -2147,7 +2147,7 @@ PICT # тайп тайпан
 'sp-contributions-submit' => 'Лаха',
 
 # What links here
-'whatlinkshere' => 'Ð¥Ñ\8cажоÑ\80агаÑ\88 ÐºÑ\85Ñ\83зе',
+'whatlinkshere' => 'Хьажоргаш кхузе',
 'whatlinkshere-title' => 'ХӀокхунца «$1» йолу агӀонаш',
 'whatlinkshere-page' => 'Агlо:',
 'linkshere' => "ТӀаьхьайогӀу агӀонаш оцу '''[[:$1]]''': хьажорагца ю",
@@ -2158,10 +2158,10 @@ PICT # тайп тайпан
 'isimage' => 'Файлан хьажораг',
 'whatlinkshere-prev' => '{{PLURAL:$1|1=хьалхайодарг|хьалхайодарш}} $1',
 'whatlinkshere-next' => '{{PLURAL:$1|тlаьхьайогlург|тlаьхьайогlурш|тlаьхьайогlурш}} $1',
-'whatlinkshere-links' => 'â\86\90 Ñ\85Ñ\8cажоÑ\80агаÑ\88',
-'whatlinkshere-hideredirs' => '$1 дlасахьажйар',
+'whatlinkshere-links' => '← хьажоргаш',
+'whatlinkshere-hideredirs' => '$1 дӀасахьажорш',
 'whatlinkshere-hidetrans' => '$1 латораш',
-'whatlinkshere-hidelinks' => '$1 Ñ\85Ñ\8cажоÑ\80агаÑ\88',
+'whatlinkshere-hidelinks' => '$1 хьажоргаш',
 'whatlinkshere-hideimages' => '$1 файлийн хьажорагаш',
 'whatlinkshere-filters' => 'Литтарш',
 
@@ -2504,7 +2504,7 @@ PICT # тайп тайпан
 'newimages' => 'Керлачу файлийн галерей',
 'newimages-summary' => 'ХӀокху белхан агӀона чохь гойтуш ю дукха хан йоццуш чуйаьхна файлаш.',
 'newimages-legend' => 'Литтар',
-'showhidebots' => '$1 шабелхалой',
+'showhidebots' => '$1 боташ',
 'ilsubmit' => 'Лаха',
 'bydate' => 'терахьашца',
 'sp-newimages-showfrom' => 'Гайта керла файлаш $2, $1 тӀера дуьйна',
@@ -2823,7 +2823,7 @@ MediaWiki яржош ю и шуна пайдане хир яц те аьлла,
 'tags-active-header' => 'Жигара?',
 'tags-hitcount-header' => 'Къастам бина нисдарш',
 'tags-active-yes' => 'ХӀаъ',
-'tags-edit' => 'нисйé',
+'tags-edit' => 'нисъе',
 'tags-hitcount' => '$1 {{PLURAL:$1|хийцам|хийцамаш|хийцамаш}}',
 
 # Special:ComparePages
index 5488a6b..1deb858 100644 (file)
@@ -193,9 +193,9 @@ $messages = array(
 'tog-extendwatchlist' => 'لیستی چاودێری درێژبکەرەوە بۆ نیشان دانی ھەموو گۆڕانکارییەکان، نەک تەنھا دوایینەکان.',
 'tog-usenewrc' => 'گۆڕانکارییەکان لە دوایین گۆڕانکارییەکان و لیستی چاودێریدا بە پێی پەڕە پۆلێن بکە (پێویستی بە جاڤاسکریپتە)',
 'tog-numberheadings' => 'ژمارەکردنی خۆگەڕی سەردێڕەکان',
-'tog-showtoolbar' => 'شرÛ\8cتÛ\8c Ø¦Ø§Ù\85رازÛ\95کاÙ\86Û\8c Ø¯Û\95ستکارÛ\8c Ù\86Û\8cشاÙ\86 Ø¨Ø¯Û\95 (JavaScript Ù¾Û\8eÙ\88Û\8cستÛ\95)',
-'tog-editondblclick' => 'دەستکاریی پەڕە بە دووکلیک لەسەر دەق (JavaScript پێویستە)',
-'tog-editsectiononrightclick' => 'ڕێگە بدە بۆ دەستکاری کردنی بەشەکان لە ڕێگەی کلیکی ڕاست کردن لەسەر سەردێڕی بەشەکان (JavaScript پێویستە)',
+'tog-showtoolbar' => 'تÙ\88Ù\88ڵاÙ\85رازÛ\8c Ø¯Û\95ستکارÛ\8c Ù\86Û\8cشاÙ\86 Ø¨Ø¯Û\95',
+'tog-editondblclick' => 'دەستکاریی پەڕە بە دووکرتە',
+'tog-editsectiononrightclick' => 'دەستکاریی بەشەکان بە کرتەی ڕاست لەسەر سەردێڕی بەشەکان',
 'tog-rememberpassword' => 'چوونە ژوورەوەم لەسەر ئەم وێبگەڕە پاشەکەوت بکە (ئەو پەڕی $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ە)',
 'tog-watchcreations' => 'ئەو پەڕانەی من دروستم کردوون و ئەو پەڕگانە من بارم کردوون زیاد بکە بە لیستی چاودێڕییەکەم',
 'tog-watchdefault' => 'ئەو پەڕانە  و ئەو پەڕگانە من دەستکاریان دەکەم زیاد بکە بە لیستی چاودێڕییەکەم',
@@ -211,7 +211,7 @@ $messages = array(
 'tog-shownumberswatching' => 'ژمارەی بەکارھێنەرە چاودێڕەکان نیشان بدە',
 'tog-oldsig' => 'واژووی ئێستا:',
 'tog-fancysig' => 'وەکوو ویکیدەق واژووەکە لەبەر چاو بگرە (بێ بەستەرێکی خۆگەڕ)',
-'tog-uselivepreview' => 'لە پێشبینینی زیندوو کەڵک وەرگرە (جاڤاسکریپت پێویستە) (تاقیکاری‌)',
+'tog-uselivepreview' => 'لە پێشبینینی زیندوو کەڵک وەربگرە (تاقیکاری‌)',
 'tog-forceeditsummary' => 'ئەگەر کورتەی دەستکاریم نەنووسی پێم بڵێ',
 'tog-watchlisthideown' => 'دەستکارییەکانم بشارەوە لە پێرستی چاودێری',
 'tog-watchlisthidebots' => 'دەستکارییەکانی بات بشارەوە لە لیستی چاودێری',
@@ -457,8 +457,8 @@ $1',
 'youhavenewmessages' => '$1ت ھەیە ($2).',
 'youhavenewmessagesfromusers' => 'لە {{PLURAL:$3|بەکارھێنەرێک|$3 بەکارھێنەران}} $1ت ھەیە ($2).',
 'youhavenewmessagesmanyusers' => '$1ت  لە ژمارەیەک بەکارھێنەر ھەیە ( $2 ).',
-'newmessageslinkplural' => '{{PLURAL:$1|پەیامێکی نوێ|پەیامی نوێ}}',
-'newmessagesdifflinkplural' => 'دوایین {{PLURAL:$1|گۆڕانکاری|گۆڕانکارییەکان}}',
+'newmessageslinkplural' => '{{PLURAL:$1|پەیامێکی نوێ|999=پەیامی نوێ}}',
+'newmessagesdifflinkplural' => 'دوایین {{PLURAL:$1|گۆڕانکاری|999=گۆڕانکارییەکان}}',
 'youhavenewmessagesmulti' => 'لە $1 دا پەیامی نوێت ھەیە',
 'editsection' => 'دەستکاری',
 'editold' => 'دەستکاری',
@@ -671,7 +671,7 @@ $2',
 تکایە هەوڵ بدەوە.',
 'passwordtooshort' => 'تێپەڕوشەکەت لانی کەم دەبێ {{PLURAL:$1|١ پیت|$1 پیت}} بێت.',
 'password-name-match' => 'تێپەڕوشەکەت ئەبێ جیاواز بێت لە ناوی بەکارهێنەریت.',
-'mailmypassword' => 'تێپەڕوشەیەکی نوێ بنێرە بۆ ئیمەیلەکەم',
+'mailmypassword' => 'تێپەڕوشەکە ڕێک بخەوە',
 'passwordremindertitle' => 'تێپەڕوشەیەکی نوێی کاتی بۆ  {{SITENAME}}',
 'passwordremindertext' => 'کەسێک (لەوانەیە خۆت، لە ئای‌پی ئەدرەسی $1) داوای تێپەڕوشەیەکی نوێی کردووە بۆ {{SITENAME}} ($4). تێپەڕوشەیەکی کاتی بۆ بەکارهێنەر «$2» دروستکراو و وەک «$3» دانراوه. ئەگەر ئەمە داخوازی تۆ بووە، پێویستت بەوەیە ئێستا بچیتە ژوورەوە و تێپەڕوشەیەکی نوێ هەڵبژێریت. ماوەی‌ تێپەڕوشە کاتییەکەت لە {{PLURAL:$5|یەک ڕۆژدا|$5 ڕۆژدا}} بەسەردەچێت.
 
@@ -681,16 +681,16 @@ $2',
 'passwordsent' => 'تێپەڕوشەیەکی نوێ ناردرا بۆ ئەدرەسی ئیمەیلی تۆمارکراوی «$1».
 تکایە دوای وەرگرتنی دیسان بچۆ ژوورەوە.',
 'blocked-mailpassword' => 'ئادرەسی ئای‌پی تۆ بۆ دەستکاری کردن بەستراوه بۆیە بۆ بەرگری لە بەکارهێنانی نابەجێ ئەنجامی گەڕانەوەی تێپەڕوشە ڕیگە نەدراوە.',
-'eauthentsent' => 'ئی‌مەیلێکی بڕواپێکردن ناردرا بۆ ئەدرەسی ئی‌مەیلی پاڵێوراو. <br />
-پێش ئەوەی ئی‌مەیلی‌تر بنێردرێ بۆ ئەم هەژمارە، بۆ ئەوەی بڕوات پێ‌بکرێ کە ئەو هەژمارە بەڕاستی هین تۆیە، دەبێ ڕێنوماییەکانی ناو ئەو ئی‌مەیلە هەنگاو بە هەنگاو ئەنجام بدەیت.',
+'eauthentsent' => 'ئیمەیلێکی پشتڕاستکردنەوە بۆ ناونیشانی ئیمەیلی دیاریکراو ناردرا.
+پێش ئەوەی ئیمەیلی تر بۆ ئەم هەژمارە بنێردرێ، بۆ پشتڕاستکردنەوەی ئەمەی ئەم هەژمارە بەڕاستی ھی تۆیە، دەبێ پەیڕەوی ڕێکارەکانی ناو ئیمەیلەکە بکەیت.',
 'throttled-mailpassword' => 'بیرهێنەرەوەیەکی وشەی نهێنی پێش ئەمە لە {{PLURAL:$1|کاتژمێر}}ی ڕابردوودا ناردراوە.
 بۆ بەرگری لە بەکارهێنانی خراپ، تاکە یەک بیرهێنەرەوەی وشەی نهێنی هەر {{PLURAL:$1|کاتژمێر}} دەنێردرێت.',
 'mailerror' => 'هەڵە ڕوویدا لە ناردنی ئیمەیل: $1',
 'acct_creation_throttle_hit' => 'بینەرانی ویکی بەکەڵک وەرگرتن لەم ئای‌پی ئەدرەسەی تۆ لە ڕۆژانی ڕابردوودا، دەستیان کردە بە درووست‌کردنی {{PLURAL:$1|هەژمارە}}، کە زۆرینە ڕیگەپێدان لە یەک ماوە‌دایە.
 وەک ئەنجامی ئەو ڕووداوە، ئەو بینەرانی لەم ئای‌پی ئەدرەسە کەڵک وەر دەگرن لەم کاتەدا ناتوانن هەژماری دیکە درووست‌بکەن.',
-'emailauthenticated' => 'ئیمەیلەکەت بە ڕاست ناسرا لە $3ی $2 دا',
-'emailnotauthenticated' => 'ئیمەیلەکەت ھێشتا نەناسراوە.
-Ú¾Û\8cÚ\86 Ø¦Û\8cÙ\85Û\95Û\8cÙ\84Û\8eÚ© Ø¨Û\86 Ø¦Û\95Ù\85 Ø¨Ø§Ø¨Û\95تاÙ\86Û\95Û\8c Ø®Ù\88ارەوە نانێردرێت.',
+'emailauthenticated' => 'ناونیشانی ئیمەیلەکەت پشتڕاست کرایەوە لە $3ی $2دا.',
+'emailnotauthenticated' => 'ناونیشانی ئیمەیلەکەت ھێشتا پشتڕاست نەکراوتەوە.
+Ú¾Û\8cÚ\86 Ø¦Û\8cÙ\85Û\95Û\8cÙ\84Û\8eÚ© Ø¨Û\86 Ø¦Û\95Ù\85 ØªØ§Û\8cبÛ\95تÙ\85Û\95Ù\86دÛ\8cÛ\8cاÙ\86Û\95Û\8c Ú\98Û\8eرەوە نانێردرێت.',
 'noemailprefs' => 'بۆ کەوتنە کاری ئەو تایبەتمەندیانە، لە هەڵبژاردەکانت ئەدرەسەکی ئی‌مێڵ دابین بکە.',
 'emailconfirmlink' => 'ئیمەیلەکەت پشت‌ڕاست بکەرەوە',
 'invalidemailaddress' => 'ناونیشانی ئیمەیل پەسند نەکرا، چون لەوە دەچێت شێوازێکی نادروستی ھەبێت.
@@ -706,6 +706,7 @@ $2',
 'login-throttled' => 'ژمارەیەکی زۆر هەوڵت داوە بۆ چوونە ژوورەوە.
 تکایە پێش هەوڵی دووبارە، نەختێک بوەستە.',
 'loginlanguagelabel' => 'زمان: $1',
+'pt-userlogout' => 'بچۆ دەرەوە',
 
 # Change password dialog
 'changepassword' => 'تێپەڕوشە بگۆڕە',
@@ -1082,15 +1083,15 @@ $3 هۆکاری "$2" خستوەتەڕوو',
 * بڵاوکردنەوەی زانیاریی تاکەکەسی نەگونجاو<br />
 *: '' ناونیشانی ماڵ یا ژمارە تەلەفۆن و وەک ئەمانە.''<br />",
 'revdelete-legend' => 'سنووردارکردنی دەرکەوتن',
-'revdelete-hide-text' => 'شاردÙ\86Û\95Ù\88Û\95Û\8c Ø¯Û\95Ù\82Û\8c Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95',
+'revdelete-hide-text' => 'دەقی پێداچوونەوە',
 'revdelete-hide-image' => 'ناوەڕۆکی پەڕگە بشارەوە',
 'revdelete-hide-name' => 'داشاردنی مەبەست و کردەوە',
-'revdelete-hide-comment' => 'شاردنەوەی کورتەی دەستکاری',
-'revdelete-hide-user' => 'شاردÙ\86Û\95Ù\88Û\95Û\8c Ù\86اÙ\88Û\8c Ø¨Û\95کارھÛ\8eÙ\86Û\95رÛ\8c/ئاÛ\8c\80\8cÙ¾Û\8c Ø¯Û\95ستکارÛ\8cÚ©Û\95ر',
+'revdelete-hide-comment' => 'کورتەی دەستکاری',
+'revdelete-hide-user' => 'Ù\86اÙ\88Û\8c Ø¨Û\95کارھÛ\8eÙ\86Û\95ر/Ù\86اÙ\88Ù\86Û\8cشاÙ\86Û\8c Ø¦Ø§Û\8cÙ¾Û\8c Ø¯Û\95ستکارÛ\8cÚ©Û\95ر',
 'revdelete-hide-restricted' => 'بەرگری دراوە لە بەڕێوبەران هەر وەک ئەوانی دیکە',
 'revdelete-radio-same' => '(مەیگۆڕە)',
-'revdelete-radio-set' => 'بÛ\95ÚµÛ\8e',
-'revdelete-radio-unset' => 'نا',
+'revdelete-radio-set' => 'شاردراÙ\88Û\95',
+'revdelete-radio-unset' => 'دیار',
 'revdelete-suppress' => 'بەرگری دراوە لە بەڕێوبەران هەر وەک ئەوانی دیکە',
 'revdelete-unsuppress' => 'لابردنی بەربەستەکان لە سەر پێداچوونەوە گەڕێندراوەکان',
 'revdelete-log' => 'هۆکار:',
@@ -1185,7 +1186,7 @@ $1",
 'shown-title' => 'لە هەر پەڕەیەک $1 {{PLURAL:$1|ئەنجام|ئەنجام}} نیشان‌ بدە',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) ببینە',
 'searchmenu-exists' => "'''پەڕەیەک بە ناوی «[[:$1]]» لەم ویکییەدا ھەیە.'''",
-'searchmenu-new' => "'''لەم ویکییەدا پەڕەی « [[:$1]] » دروست بکە!'''",
+'searchmenu-new' => '<strong>لەم ویکییەدا پەڕەی « [[:$1]] » دروست بکە!</strong> {{PLURAL:$2|0=|ھەروەھا بڕوانە پەڕەی دۆزراوەی گەڕانەکەت.|ھەروەھا بڕوانە ئاکامە دۆزراوەکانی گەڕانەکە.}}',
 'searchprofile-articles' => 'پەڕە بە ناوەڕۆکەکان',
 'searchprofile-project' => 'پەڕەکانی یارمەتی و پرۆژە',
 'searchprofile-images' => 'ڕەنگاڵە',
@@ -1250,7 +1251,7 @@ $1",
 'prefs-email' => 'ھەڵبژاردەکانی ئیمەیل',
 'prefs-rendering' => 'ڕواڵەت',
 'saveprefs' => 'پاشەکەوت',
-'restoreprefs' => 'ھەموو ڕێکخستنەکان ببەرەوە بۆ باری بنچینەیی',
+'restoreprefs' => 'ھەموو ڕێکخستنەکان ببەرەوە بۆ باری بنچینەیی (لە ھەموو بەشەکاندا)',
 'prefs-editing' => 'دەستکاریکردن',
 'rows' => 'ڕیزەکان:',
 'columns' => 'ستوونەکان:',
@@ -1303,8 +1304,8 @@ $1",
 'badsig' => 'ئیمزاكه‌ هه‌ڵه‌یه‌، ته‌ماشای كۆدی HTML بكه‌‌',
 'badsiglength' => 'واژووەکەت زۆر درێژە.
 واژوو نابێ لە $1 {{PLURAL:$1|نووسە}} درێژتر بێت.',
-'yourgender' => 'زایەند:',
-'gender-unknown' => 'ئاشکرا نەکراو',
+'yourgender' => 'پێت خۆشە چۆن وەسف بکرێیت؟',
+'gender-unknown' => 'پێم خۆشە باسی نەکەم',
 'gender-male' => 'پیاو',
 'gender-female' => 'ژن',
 'prefs-help-gender' => 'دڵخواز: بۆ بانگ کردنی دروست بە دەستی نەرمامێر.
@@ -1483,8 +1484,8 @@ $1",
 'action-block' => 'بەربەست کردنی ئەم بەکارهێنەرە بۆ دەستکاری‌کردن',
 'action-protect' => 'گۆڕانی ئاستی پارێزراوی بۆ ئەم لاپەڕە',
 'action-rollback' => 'گەڕاندنەوەی خێرای دەستکاریەکانی دوایین بەکارھێنەر کە پەڕەیەکی دیاریکراوی دەستکاری کردووە',
-'action-import' => 'هێنانەناوەی ئەم لاپەڕە لە ویکی‌یەکی دیکە',
-'action-importupload' => 'هێنانەناوەی ئەم لاپەڕە لە پەڕگەیەکی بارکراو',
+'action-import' => 'ھاوردنی پەڕەکان لە ویکییەکی ترەوە',
+'action-importupload' => 'ھاوردنی پەڕەکان لە پەڕگەیەکی بارکراو',
 'action-patrol' => 'نیشانکردنی دەستکاریەکانی کەسانی تر وەک پاس دراو',
 'action-autopatrol' => 'دەستکارییەکانت وەک پاس دراو نیشان بکرێ',
 'action-unwatchedpages' => 'دیتنی پێرستێک لە پەڕە چاودێری نەکراوەکان',
@@ -1508,14 +1509,24 @@ $1",
 'recentchanges-legend-heading' => "'''کورتکراوەکان:'''",
 'recentchanges-legend-newpage' => '(ھەروەھا بڕوانە [[Special:NewPages|پێرستی پەڕە نوێکان]])',
 'recentchanges-legend-plusminus' => "(''±۱٢٣'')",
-'rcnotefrom' => "ئەوی‌ خوارەوە گۆڕانکارییەکانە لە '''$2'''ەوە (ھەتا '''$1''' نیشاندراو).",
+'rcnotefrom' => 'ژێرەوە گۆڕانکارییەکانە لە <strong>$2</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).',
 'rclistfrom' => 'گۆڕانکارییە نوێکان نیشان بدە بە دەستپێکردن لە $1',
 'rcshowhideminor' => 'دەستکارییە بچووکەکان $1',
+'rcshowhideminor-show' => 'نیشان بدە',
+'rcshowhideminor-hide' => 'بشارەوە',
 'rcshowhidebots' => 'بۆتەکان $1',
+'rcshowhidebots-show' => 'نیشان بدە',
+'rcshowhidebots-hide' => 'بشارەوە',
 'rcshowhideliu' => 'بەکارھێنەرە تۆمارکراوەکان $1',
+'rcshowhideliu-show' => 'نیشان بدە',
+'rcshowhideliu-hide' => 'بشارەوە',
 'rcshowhideanons' => 'بەکارھێنەرە نەناسراوەکان $1',
+'rcshowhideanons-show' => 'نیشان بدە',
+'rcshowhideanons-hide' => 'بشارەوە',
 'rcshowhidepatr' => 'گۆرانکارییە پاس دراوەکان $1',
 'rcshowhidemine' => 'دەستکارییەکانم $1',
+'rcshowhidemine-show' => 'نیشان بدە',
+'rcshowhidemine-hide' => 'بشارەوە',
 'rclinks' => 'دوایین $1 گۆڕانکاریی $2 ڕۆژی ڕابردوو نیشان بدە<br />$3',
 'diff' => 'جیاوازی',
 'hist' => 'مێژوو',
@@ -1529,7 +1540,7 @@ $1",
 'rc_categories_any' => 'هەرکام',
 'rc-change-size-new' => '$1 {{PLURAL:$1|بایت}} پاش گۆڕانکاری',
 'newsectionsummary' => '/* $1 */ بەشی نوێ',
-'rc-enhanced-expand' => 'Ù\88ردÛ\95کارÛ\8cÛ\8cÛ\95کاÙ\86 Ù¾Û\8cشاÙ\86 Ø¨Ø¯Û\95 (Ù¾Û\8eÙ\88Û\8cستÛ\8c Ø¨Û\95 Ø¬Ø§Ú¤Ø§Ø³Ú©Ø±Û\8cپتÛ\95)',
+'rc-enhanced-expand' => 'Ù\88ردÛ\95کارÛ\8cÛ\8cÛ\95کاÙ\86 Ù\86Û\8cشاÙ\86 Ø¨Ø¯Û\95',
 'rc-enhanced-hide' => 'وردەکارییەکان بشارەوە',
 'rc-old-title' => 'بە ناوی سەرەکیی «$1» دروست کراوە',
 
@@ -1708,8 +1719,7 @@ $1',
 'upload_source_file' => ' (پەڕگەیەک لەسەر کۆمپیوتەرەکەت)',
 
 # Special:ListFiles
-'listfiles-summary' => 'ئەم پەڕە تایبەتە هەموو پەڕگە بارکراوەکانت پێ نیشان دەدات.
-لە کاتی پاڵاوتن بۆ بەکارھێنەرێکی تایبەت، تەنیا ئەو پەڕگانە کە بەکارھێنەرەکە دوایین وەشانیانی بارکردبێت نیشان دەدرێن.',
+'listfiles-summary' => 'ئەم پەڕە تایبەتە ھەموو پەڕگە بارکراوەکان نیشان دەدات.',
 'listfiles_search_for' => 'بگەڕێ بۆ ناوی میدیای:',
 'imgfile' => 'پەڕگە',
 'listfiles' => 'پێرستی پەڕگەکان',
@@ -2316,7 +2326,7 @@ $1',
 'contributions' => 'بەشدارییەکانی {{GENDER:$1|بەکارھێنەر}}',
 'contributions-title' => 'بەشدارییەکانی بەکارھێنەر $1',
 'mycontris' => 'بەشدارییەکان',
-'contribsub2' => 'بۆ $1 ($2)',
+'contribsub2' => 'بۆ {{GENDER:$3|$1}} ($2)',
 'nocontribs' => 'هیچ گۆڕانکاریەکی هاوتای ئەم پێوەرانە نودۆزرایەوە',
 'uctop' => '(ھەنووکە)',
 'month' => 'لە مانگی (و پێشترەوە):',
@@ -2660,7 +2670,7 @@ $1',
 بوخچەیەکی کاتی بزر بووە.',
 'import-parse-failure' => 'سەرنەکەوتن لە شیکردنەوەی ھاوردنی XML',
 'import-noarticle' => 'ھیچ پەڕەیەک بۆ ھاوردن نییە!',
-'import-nonewrevisions' => 'Ú¾Û\95Ù\85Ù\88Ù\88 Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95کاÙ\86 Ù¾Û\8eشتر Ú¾Ø§Ù\88ردÛ\95 Ú©Ø±Ø§Ù\88Ù\86.',
+'import-nonewrevisions' => 'Ú¾Û\8cÚ\86 Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95Û\8cÛ\95Ú© Ú¾Ø§Ù\88ردÛ\95 Ù\86Û\95کراÙ\88Û\95 (Ú¾Û\95Ù\85Ù\88Ù\88Û\8c Û\8cا Ú¾Û\95ر Ø¦Û\8eستا Ú¾Û\95Û\8cÛ\95Ø\8c Û\8cاÙ\86 Ù\84Û\95بÛ\95ر Ú¾Û\95ÚµÛ\95کاÙ\86 Ú\86اÙ\88Ù¾Û\86Ø´Û\8c Ù\84Û\8e Ú©Ø±Ø§Ù\88Û\95).',
 'xml-error-string' => '$1 لە دێڕی $2، ستوونی $3 (بایت $4): $5',
 'import-upload' => 'بارکردنی دراوەی XML',
 'import-token-mismatch' => 'لەدەستدانی دراوەکانی کۆڕ.
@@ -2787,12 +2797,12 @@ $1',
 'pageinfo-article-id' => 'زنجیرەی پەڕە',
 'pageinfo-language' => 'زمانی ناوەرۆکی پەڕە',
 'pageinfo-robot-policy' => 'چۆنێتیی مۆتۆڕی گەڕان',
-'pageinfo-robot-index' => 'شیاو بۆ پێرستکردن',
-'pageinfo-robot-noindex' => 'نەشیاو بۆ پێرستکردن',
+'pageinfo-robot-index' => 'ڕێ پێدراو',
+'pageinfo-robot-noindex' => 'ڕێ پێنەدراوه',
 'pageinfo-views' => 'ژمارەی بینینەکان',
 'pageinfo-watchers' => 'ژمارەی چاودێرانی پەڕە',
 'pageinfo-few-watchers' => 'کەمتر لە $1 {{PLURAL:$1|چاودێر}}',
-'pageinfo-redirects-name' => 'ڕەوانەکەرەکان بۆ ئەم پەڕەیە',
+'pageinfo-redirects-name' => 'Ú\98Ù\85ارÛ\95Û\8c Ú\95Û\95Ù\88اÙ\86Û\95Ú©Û\95رÛ\95کاÙ\86 Ø¨Û\86 Ø¦Û\95Ù\85 Ù¾Û\95Ú\95Û\95Û\8cÛ\95',
 'pageinfo-subpages-name' => 'ژێرپەڕەکانی ئەم پەڕەیە',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|ڕەوانەکەر}}; $3 {{PLURAL:$3|ڕەوانەنەکەر}})',
 'pageinfo-firstuser' => 'دروستکەری پەڕە',
@@ -2862,7 +2872,7 @@ $1',
 'file-nohires' => 'رەزۆلوشنی سەرتر لەمە لە بەردەست دا نیە.',
 'svg-long-desc' => 'پەڕگەی SVG، بە ناو $1 × $2 پیکسەڵ، قەبارەی پەڕگە: $3',
 'svg-long-error' => 'پەڕگەی SVGی نادروست: $1',
-'show-big-image' => 'گەورەکردنەوە',
+'show-big-image' => 'پەڕگەی سەرەکی',
 'show-big-image-preview' => 'قەبارەی ئەم پێشبینینە: $1.',
 'show-big-image-other' => '{{PLURAL:$2|ڕەزەلووشنی|ڕەزەلووشنەکانی}} تر: $1.',
 'show-big-image-size' => '$1 لە $2 پیکسەڵ',
@@ -3220,18 +3230,18 @@ $3
 $5
 
 ئەم کۆدی بڕواپێکردنە لە $4 ماوەی بەسەردێت.',
-'confirmemail_body_set' => 'کەسێک، لەوانەیە خۆت، لە ئای‌پی ئەدرەسی $1،
-ئەدرەسی ئەیمەیلی ھەژماری «$2» لە {{SITENAME}}دا کردووە بەم ئەدرەسە.
+'confirmemail_body_set' => 'کەسێک، لەوانەیە خۆت، لە ناونیشانی ئایپیی $1،
+ناونیشانیی ئەیمەیلی ھەژماری «$2» لە {{SITENAME}}دا کردووە بەم ناونیشانە.
 
-بۆ ئەوەی بڕوا بکرێت کە ئەم ھەژمارە لە ڕاستیدا بۆتۆیە و بۆ چالاککردنەوەی تایبەتمەندیەکانی ئیمەیل لە {{SITENAME}}دا، ئەم بەستەرەی خوارەوە لە وێبگەڕەکەتدا بکەوە:
+بۆ پشتڕاستکردنەوەی ئەمەی ئەم ھەژمارە بەڕاستی ھی تۆیە و بۆ چالاککردنی تایبەتمەندیەکانی ئیمەیل لە {{SITENAME}}دا، ئەم بەستەرە لە وێبگەڕەکەتدا بکەوە:
 
 $3
 
-ئەگەر ھەژمارە ھی تۆ *نییە*، بۆ هەڵوەشاندنەوەی بڕوا‌پێکردنی ئەدرەسی ئیمەیل بەدوای ئەم بەستەرە بکەوە:
+ئەگەر ھەژمارەکە ھی تۆ *نییە*، بۆ هەڵوەشاندنەوەی پشتڕاستکردنەوەی ناونیشانی ئیمەیل، شوێنی ئەم بەستەرە بکەوە:
 
 $5
 
-ئÛ\95Ù\85 Ú©Û\86دÛ\8c Ø¨Ú\95Ù\88اپÛ\8eکردÙ\86Û\95 Ù\84Û\95 $4 Ù\85اÙ\88Û\95Û\8c Ø¨Û\95سÛ\95ردێت.',
+ئÛ\95Ù\85 Ú©Û\86دÛ\95Û\8c Ù¾Ø´ØªÚ\95استکردÙ\86Û\95Ù\88Û\95Û\8cÛ\95 Ù\84Û\95 $4 Ù\85اÙ\88Û\95Û\8c Ø¨Û\95سÛ\95ر Ø¯Û\95Ú\86ێت.',
 'confirmemail_invalidated' => 'بڕواپی‌کردنی ناونیشانی ئی‌مەیل هەڵوەشێندراوە',
 'invalidateemail' => 'هەڵوەشاندنەوەی بڕواپێ‌کردنی ئی‌مەیل',
 
@@ -3377,7 +3387,7 @@ $5
 'version-hook-name' => 'ناوی قولاپ',
 'version-hook-subscribedby' => 'بەشداربوو لە لایەن',
 'version-version' => '(وەشانی $1)',
-'version-license' => 'مۆڵەت',
+'version-license' => 'مۆڵەتنامە',
 'version-poweredby-others' => 'دیکە',
 'version-software' => 'نەرمەکاڵای دامەزراو',
 'version-software-product' => 'بەرهەم',
index c9a98a6..39ddeb0 100644 (file)
@@ -706,7 +706,7 @@ Správce serveru, který databázi zamkl, poskytl toto zdůvodnění: $1',
 
 Toto je obvykle způsobeno tím, že jste následovali zastaralý odkaz na rozdíl verzí nebo historickou verzi stránky, jež byla smazána.
 
-Pokud toto není váš případ, možná jste nalezli chybu v software. Prosíme, ohlaste to [[Special:ListUsers/sysop|správcům]] spolu s URL této stránky.',
+Není-li toto váš případ, možná jste nalezli chybu v softwaru. Prosíme, ohlaste to [[Special:ListUsers/sysop|správcům]] spolu s URL této stránky.',
 'missingarticle-rev' => '(číslo revize: $1)',
 'missingarticle-diff' => '(Rozdíl: $1, $2)',
 'readonly_lag' => 'Databáze byla automaticky dočasně uzamčena kvůli zpoždění ostatních databázových serverů oproti hlavnímu',
index 3e538a3..8f91a12 100644 (file)
@@ -647,7 +647,7 @@ Oedwch $1 cyn mentro eto.',
 'suspicious-userlogout' => 'Gwrthodwyd eich cais i allgofnodi oherwydd ei fod yn ymddangos mai gweinydd wedi torri neu ddirprwy gelc a anfonodd y cais.',
 'createacct-another-realname-tip' => "Gallwch ddewis roi eich enw go iawn.
 Os y gwnewch, fe gaiff yr enw go iawn ei defnyddio wrth dadogi'ch gwaith.",
-'pt-login' => 'Mewngofnodwch',
+'pt-login' => 'Mewngofnoder',
 'pt-createaccount' => 'Creu cyfri',
 'pt-userlogout' => 'Allgofnodi',
 
@@ -678,7 +678,7 @@ Gall fod eich bod wedi llwyddo newid eich cyfrinair eisoes neu eich bod wedi gof
 'resetpass-temp-password' => 'Cyfrinair dros dro:',
 'resetpass-abort-generic' => 'Mae estyniad wedi atal newid y cyfrinair.',
 'resetpass-expired' => 'Mae oes eich cyfrinair wedi dod i ben. Gosodwch gyfrinair newydd i fewngofnodi.',
-'resetpass-expired-soft' => "Mae eich cyfrinair wedi dod i ben ac mae'n rhaid ei ailosod. Dewisiwch gyfrinair newydd sbon nawr, neu ailosodwch ef rywdro eto.",
+'resetpass-expired-soft' => 'Mae eich cyfrinair wedi dod i ben ac mae\'n rhaid ei ailosod. Dewisiwch gyfrinair newydd sbon nawr, neu cliciwch "{{int:resetpass-submit-cancel}}" a\'i ailosod rywdro eto.',
 
 # Special:PasswordReset
 'passwordreset' => 'Ailosod cyfrinair',
@@ -938,7 +938,7 @@ Mae ar gael yn barod.',
 'editwarning-warning' => 'Os y gadewch y dudalen hon mae\'n bosib y collwch eich newidiadau iddi.
 Os ydych wedi mewngofnodi gallwch ddiddymu\'r rhybudd hwn yn yr adran "{{int:prefs-editing}}" yn eich dewisiadau.',
 'editpage-notsupportedcontentformat-title' => 'Dydy fformat y cynnwys hwn ddim yn cael ei gefnogi gennym.',
-'editpage-notsupportedcontentformat-text' => 'Dydy fformat y cynnwys ddim yn cael ei gefnogi gan gynnwys model $2.',
+'editpage-notsupportedcontentformat-text' => "Dydy'r fformat $1 ar y cynnwys ddim yn cael ei gefnogi gan y model $2.",
 
 # Content models
 'content-model-wikitext' => 'cystrawen wici',
@@ -1153,7 +1153,8 @@ Pan yn gwneud hyn dylid sicrhau nad yw dilyniant hanes tudalennau yn cael ei ddi
 'showhideselectedversions' => 'Dangos/cuddio y diwygiadau dewisedig',
 'editundo' => 'dadwneud',
 'diff-empty' => '(Dim gwahaniaeth)',
-'diff-multi-sameuser' => 'Mae ({{PLURAL:$1|un golygiad|$1 golygiadau}} gan yr un defnyddiwr heb ei ddangos.',
+'diff-multi-sameuser' => '(Ni ddangosir y {{PLURAL:$1||golygiad|$1 olygiad|$1 golygiad}} yn y canol gan yr un defnyddiwr)',
+'diff-multi-otherusers' => '(Ni ddangosir y {{PLURAL:$1||golygiad|$1 olygiad|$1 golygiad}} yn y canol gan {{PLURAL:$2||ddefnyddiwr|$2 ddefnyddiwr|$2 defnyddiwr}} arall)',
 'diff-multi-manyusers' => '(Ni ddangosir {{PLURAL:$1|yr $1 diwygiad|yr $1 diwygiad|y $1 ddiwygiad|y $1 diwygiad|y $1 diwygiad|y $1 diwygiad}} rhyngol gan mwy na $2 {{PLURAL:$2|o ddefnyddwyr}}.)',
 'difference-missing-revision' => "Ni chafwyd hyd i $1 {{PLURAL:$2|diwygiad|diwygiad|ddiwygiad|diwygiad}} o'r gwahaniaeth ($1) {{PLURAL:$2|hwn}}.
 
@@ -1199,7 +1200,7 @@ Mae manylion pellach i'w cael yn [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'searchrelated' => 'erthyglau eraill tebyg',
 'searchall' => 'oll',
 'showingresults' => "Yn dangos $1 {{PLURAL:$1|canlyniad|canlyniad|ganlyniad|chanlyniad|chanlyniad|canlyniad}} isod gan ddechrau gyda rhif '''$2'''.",
-'showingresultsinrange' => 'Yn cael ei ddangos isod yn y rhediad Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} #<strong>$2</strong> i #<strong>$3</strong>.',
+'showingresultsinrange' => 'Yn dangos hyd at {{PLURAL:$1||<strong>1</strong> canlyniad|<strong>$1</strong> ganlyniad|$1 o ganlyniadau}} isod yn yr ystod #<strong>$2</strong> i #<strong>$3</strong>.',
 'showingresultsnum' => "Yn dangos $3 {{PLURAL:$3|canlyniad|canlyniad|ganlyniad|chanlyniad|chanlyniad|canlyniad}} isod gan ddechrau gyda rhif '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5||Canlyniad '''$1''' o blith '''$3'''|Canlyniadau '''$1 - $2''' o blith '''$3'''|Canlyniadau '''$1 - $2''' o blith '''$3'''|Canlyniadau '''$1 - $2''' o blith '''$3'''|Canlyniadau '''$1 - $2''' o blith '''$3'''}} ar gyfer '''$4'''",
 'search-nonefound' => "Ni chafwyd dim canlyniadau i'r ymholiad.",
@@ -1519,14 +1520,26 @@ Mae'r wybodaeth hon ar gael i'r cyhoedd.",
 'recentchanges-legend-heading' => "'''Allwedd:'''",
 'recentchanges-legend-newpage' => '(gweler hefyd [[Special:NewPages|restr y tudalennau newydd]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Isod rhestrir pob newid ers '''$2''' (hyd at '''$1''' ohonynt).",
+'rcnotefrom' => "Isod rhestrir pob newid er <strong>'''$2'''</strong> (ymddengys hyd at <strong>'''$1'''</strong> ohonynt).",
 'rclistfrom' => 'Dangos newidiadau newydd, gan ddechrau ers $1',
 'rcshowhideminor' => '$1 golygiadau bychain',
+'rcshowhideminor-show' => 'Dangoser',
+'rcshowhideminor-hide' => 'Cuddier',
 'rcshowhidebots' => '$1 botiau',
+'rcshowhidebots-show' => 'Dangoser',
+'rcshowhidebots-hide' => 'Cuddier',
 'rcshowhideliu' => '$1 o ddefnyddwyr cofrestredig',
+'rcshowhideliu-show' => 'Dangoser',
+'rcshowhideliu-hide' => 'Cuddier',
 'rcshowhideanons' => '$1 defnyddwyr anhysbys',
+'rcshowhideanons-show' => 'Dangoser',
+'rcshowhideanons-hide' => 'Cuddier',
 'rcshowhidepatr' => '$1 golygiadau wedi derbyn ymweliad patrôl',
+'rcshowhidepatr-show' => 'Dangoser',
+'rcshowhidepatr-hide' => 'Cuddier',
 'rcshowhidemine' => '$1 fy ngolygiadau',
+'rcshowhidemine-show' => 'Dangoser',
+'rcshowhidemine-hide' => 'Cuddier',
 'rclinks' => 'Dangos y $1 newid diweddaraf yn ystod y(r) $2 diwrnod diwethaf<br />$3',
 'diff' => 'gwahan',
 'hist' => 'hanes',
@@ -1653,6 +1666,7 @@ Cyn i chi ail-lwytho'r ffeil, dylech holi i rywun â'r gallu ganddo i weld data
 'php-uploaddisabledtext' => 'Anablwyd uwchlwytho ffeiliau yn PHP.
 Gwiriwch y gosodiad ar file_uploads.',
 'uploadscripted' => "Mae'r ffeil hon yn cynnwys HTML neu sgript a all achosi problemau i borwyr gwe.",
+'uploadscriptednamespace' => "Mae'r ffeil SVG hon yn cynnwys yr enw '$1' sy'n enw annilys ar barth",
 'uploadinvalidxml' => "Ni ellid dosrannu'r XML yn y ffeil a uwchlwythwyd.",
 'uploadvirus' => 'Mae firws gan y ffeil hon! Manylion: $1',
 'uploadjava' => "Ffeil ZIP yw hwn sy'n cynnwys ffeil Java .class.
@@ -2210,7 +2224,7 @@ Pan fydd y dudalen hon, neu ei thudalen sgwrs, yn newid, fe fyddant yn ymddangos
 'watchmethod-list' => "yn chwilio'r tudalennau ar y rhestr wylio am ddiwygiadau diweddar",
 'watchlistcontains' => '{{PLURAL:$1|Nid oes dim tudalennau|Mae $1 dudalen|Mae $1 dudalen|Mae $1 tudalen|Mae $1 thudalen|Mae $1 o dudalennau}} ar eich rhestr wylio.',
 'iteminvalidname' => "Problem gyda'r eitem '$1', enw annilys...",
-'wlnote2' => 'Isod, fe welwch y newidiadau yn yr  {{PLURAL:$1|hour|<strong>$1</strong> awr diwethaf}}, a hynny ar $2, $3.',
+'wlnote2' => 'Isod, fe welwch y newidiadau yn ystod {{PLURAL:$1|yr awr|yr awr|y ddwyawr ddiwethaf|teirawr diwethaf|<strong>$1</strong> awr diwethaf}}, hyd at $2, $3.',
 'wlshowlast' => "Dangoser newidiadau'r $1 awr ddiwethaf neu'r $2 {{PLURAL:$2|diwrnod|diwrnod|ddiwrnod|diwrnod|diwrnod|diwrnod}} diwethaf neu'r $3 newidiadau.",
 'watchlist-options' => 'Dewisiadau ar gyfer y rhestr wylio',
 
@@ -2786,7 +2800,7 @@ $2',
 'thumbnail_image-type' => "Nid yw'r math hwn o ddelwedd yn cael ei gynnal",
 'thumbnail_gd-library' => 'Mae ffurfwedd y llyfrgell GD yn anghyflawn: y ffwythiant $1 yn eisiau',
 'thumbnail_image-missing' => "Mae'n debyg bod y ffeil yn eisiau: $1",
-'thumbnail_image-failure-limit' => "'Da chi 'di methu gormod o weithiau (\$ neu fwy) i rendro'r ciplun. Ceisiwch eto nes ymlaen.",
+'thumbnail_image-failure-limit' => "'Da chi 'di methu gormod o weithiau ($1 neu fwy) i rendro'r ciplun. Ceisiwch eto nes ymlaen.",
 
 # Special:Import
 'import' => 'Mewnforio tudalennau',
index 4ab4fbc..00d942b 100644 (file)
@@ -1242,7 +1242,7 @@ Vær opmæksom på at bevare kontinuiteten i sidehistorikken.
 'showhideselectedversions' => 'Vis/skjul udvalgte versioner',
 'editundo' => 'fjern redigering',
 'diff-empty' => '(Ingen forskel)',
-'diff-multi-sameuser' => '({{PLURAL:$1|En mellemliggende version|$1 mellemliggende versioner}} af den samme bruger, vises ikke)',
+'diff-multi-sameuser' => '({{PLURAL:$1|En mellemliggende version|$1 mellemliggende versioner}} af den samme bruger vises ikke)',
 'diff-multi-otherusers' => '({{PLURAL:$1|En mellemliggende version|$1 mellemliggende versioner}} af {{PLURAL:$2|en anden bruger|$2 andre brugere}} ikke vist)',
 'diff-multi-manyusers' => '({{PLURAL:$1|En mellemliggende version|$1 mellemliggende versioner}} af mere end $2 {{PLURAL:$2|bruger|brugere}} ikke vist)',
 'difference-missing-revision' => '{{PLURAL:$2|En revision|$2 revisioner}} af denne forskel ($1) {{PLURAL:$2|blev|blev}} ikke fundet.
index 27f869c..7fbfde8 100644 (file)
@@ -977,7 +977,7 @@ Wenn du ihn angibst, wird er für die Zuordnung der Beiträge verwendet.',
 
 # Change password dialog
 'changepassword' => 'Passwort ändern',
-'resetpass_announce' => 'Um die Anmeldung abzuschließen, musst du ein neues Passwort wählen.',
+'resetpass_announce' => 'Um die Anmeldung abzuschließen, musst du ein neues Passwort festlegen.',
 'resetpass_text' => '<!-- Ergänze den Text hier -->',
 'resetpass_header' => 'Passwort ändern',
 'oldpassword' => 'Altes Passwort:',
@@ -1497,7 +1497,7 @@ Einzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'shown-title' => 'Zeige $1 {{PLURAL:$1|Ergebnis|Ergebnisse}} pro Seite',
 'viewprevnext' => 'Zeige ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''Es gibt eine Seite, die den Namen „[[:$1]]“ hat.'''",
-'searchmenu-new' => '<strong>Erstelle die Seite „[[:$1]]“ in diesem Wiki.</strong> {{PLURAL:$2|0=|Siehe auch die mit deiner Suche gefundene Seite.|Siehe auch die gefundenen Suchergebnisse.}}',
+'searchmenu-new' => '<strong>Erstelle die Seite „[[:$1]]“ in diesem Wiki.</strong> {{PLURAL:$2|0=|Siehe auch die über deine Suche gefundene Seite.|Siehe auch die gefundenen Suchergebnisse.}}',
 'searchprofile-articles' => 'Inhaltsseiten',
 'searchprofile-project' => 'Hilfe- und Projektseiten',
 'searchprofile-images' => 'Multimedia',
@@ -1651,7 +1651,7 @@ Diese Information ist öffentlich.',
 'prefs-displaywatchlist' => 'Anzeigeoptionen',
 'prefs-tokenwatchlist' => 'Token',
 'prefs-diffs' => 'Versionsvergleich',
-'prefs-help-prefershttps' => 'Diese Einstellung wird bei deiner nächsten Anmeldung wirksam',
+'prefs-help-prefershttps' => 'Diese Einstellung wird bei deiner nächsten Anmeldung wirksam.',
 'prefs-tabs-navigation-hint' => 'Tipp: Du kannst die linke und rechte Pfeiltasten benutzen, um zwischen den Registerkarten in der Reiterliste zu navigieren.',
 
 # User preference: email validation using jQuery
@@ -1844,7 +1844,7 @@ Diese Information ist öffentlich.',
 'recentchanges-legend-newpage' => '(siehe auch die [[Special:NewPages|Liste neuer Seiten]])',
 'recentchanges-legend-plusminus' => "''(±123)''",
 'rcnotefrom' => 'Angezeigt werden die Änderungen seit <strong>$2</strong> (max. <strong>$1</strong> Einträge).',
-'rclistfrom' => 'Nur Änderungen seit $1 zeigen.',
+'rclistfrom' => 'Nur Änderungen seit $3, $2 Uhr zeigen.',
 'rcshowhideminor' => 'Kleine Änderungen $1',
 'rcshowhideminor-show' => 'anzeigen',
 'rcshowhideminor-hide' => 'ausblenden',
@@ -2806,6 +2806,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Diese IP-Adresse ist zurzeit gesperrt.
 Zur Information folgt der aktuelle Auszug aus dem Sperr-Logbuch:',
 'sp-contributions-search' => 'Suche nach Benutzerbeiträgen',
+'sp-contributions-suppresslog' => 'Unterdrückte Benutzerbeiträge',
 'sp-contributions-username' => 'IP-Adresse oder Benutzername:',
 'sp-contributions-toponly' => 'Nur aktuelle Versionen zeigen',
 'sp-contributions-newonly' => 'Nur Seitenerstellungen anzeigen',
index a1f4dd1..3965382 100644 (file)
@@ -659,7 +659,7 @@ Keyepelê {{SITENAME}} eşkeno xeta eşkera bıkero.',
 Seba lista pelanê xasanê vêrdeyan reca kena: [[Special:SpecialPages|{{int:specialpages}}]].',
 
 # General errors
-'error' => 'Ğeta',
+'error' => 'Xeta',
 'databaseerror' => 'Ğetay ardoği',
 'databaseerror-text' => 'Tabanda malumati de ğırabiya persayışi bi
 Na nusteber  zew ğırabin asınena.',
@@ -1433,7 +1433,7 @@ Detayê besternayışi [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}
 'powersearch-togglenone' => 'Çıniyo',
 'search-external' => 'Cıgeyrayışê teberi',
 'searchdisabled' => '{{SITENAME}} no keyepel de cıgerayiş muweqqet bıryayo. no benatê de şıma pê Google eşkeni zerreyê {{SITENAME}} de cıgerayiş bıkeri.',
-'search-error' => 'Cı geyrayış de zu ğeta emé meydan:$1',
+'search-error' => 'Cıgeyrayış de yew xeta emê meydan: $1',
 
 # Preferences page
 'preferences' => 'Tercihi',
index 6eb5555..e2351d6 100644 (file)
@@ -714,7 +714,7 @@ Sy snaź swójo gronidło južo wuspěšnje změnił abo nowe nachylne gronidło
 'resetpass-temp-password' => 'Nachylne gronidło:',
 'resetpass-abort-generic' => 'Změnjanje gronidła jo se pśez rozšyrjenje pśetergnuło.',
 'resetpass-expired' => 'Twójo gronidło jo pśepadnyło. Pšosym póstaj nowe gronidło za pśizjawjenje.',
-'resetpass-expired-soft' => 'Twójo gronidło jo pśepadnyło a musy se slědk stajiś. Pšosym wubjeŕ něnto druge gronidło abo klikni na "Pśetergnuś", aby jo pózdźej slědk stajił.',
+'resetpass-expired-soft' => 'Twójo gronidło jo pśepadnyło a musy se slědk stajiś. Pšosym wubjeŕ něnto druge gronidło abo klikni na "{{int:resetpass-submit-cancel}}", aby jo pózdźej slědk stajił.',
 
 # Special:PasswordReset
 'passwordreset' => 'Gronidło slědk stajiś',
@@ -1542,14 +1542,26 @@ Toś ta informacija buźo zjawna.',
 'recentchanges-legend-heading' => "'''Legenda:'''",
 'recentchanges-legend-newpage' => '(glej teke [[Special:NewPages|lisćinu nowych bokow]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Dołojce pokazuju se změny wót '''$2''' (maks. '''$1''' zapisow).",
+'rcnotefrom' => 'Dołojce pokazuju se změny wót <strong>$2</strong> (maks. <strong>$1</strong> zapisow).',
 'rclistfrom' => 'Nowe změny wót $1 pokazaś.',
 'rcshowhideminor' => 'Snadne změny $1',
+'rcshowhideminor-show' => 'Pokazaś',
+'rcshowhideminor-hide' => 'Schowaś',
 'rcshowhidebots' => 'awtomatiske programy (boty) $1',
+'rcshowhidebots-show' => 'Pokazaś',
+'rcshowhidebots-hide' => 'Schowaś',
 'rcshowhideliu' => 'Zregistrěrowane wužywarje $1',
+'rcshowhideliu-show' => 'Pokazaś',
+'rcshowhideliu-hide' => 'Schowaś',
 'rcshowhideanons' => 'anonymne wužywarje $1',
+'rcshowhideanons-show' => 'Pokazaś',
+'rcshowhideanons-hide' => 'Schowaś',
 'rcshowhidepatr' => 'kontrolěrowane změny $1',
+'rcshowhidepatr-show' => 'Pokazaś',
+'rcshowhidepatr-hide' => 'Schowaś',
 'rcshowhidemine' => 'móje pśinoski $1',
+'rcshowhidemine-show' => 'Pokazaś',
+'rcshowhidemine-hide' => 'Schowaś',
 'rclinks' => 'Slědne $1 změny slědnych $2 dnjow pokazaś<br />$3',
 'diff' => 'rozdźěl',
 'hist' => 'wersije',
@@ -1673,6 +1685,7 @@ Jolic maš toś ten wobraz w połnem rozeznaśu, nagraj jen, howac změń pšosy
 'uploaddisabledtext' => 'Nagraśa datajow su znjemóžnjone.',
 'php-uploaddisabledtext' => 'Nagraśa PHP-datajow su znjemóžnjone. Pšosym pśekontrolěruj nastajenje file_uploads.',
 'uploadscripted' => 'Toś ta dataja wopśimjejo HTML abo script code, kótaryž móžo wót browsera se zamólnje wuwjasć.',
+'uploadscriptednamespace' => "Toś ta SVG-dataja wopśimujo njedowólony mjenjowy rum '$1'",
 'uploadinvalidxml' => 'XML w nagratej dataji njedajo se parsowaś.',
 'uploadvirus' => 'Toś ta dataja ma wirus! Nadrobnosći: $1',
 'uploadjava' => 'Toś ta dataja jo ZIP-dataja, kótaraž wopśimujo dataju .class z Javy.
@@ -2488,8 +2501,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Toś ta IP-adresa jo tuchylu zablokěrowana.
 Nejnowšy zapisk protokola blokěrowanjow pódawa se dołojce ako referenca:',
 'sp-contributions-search' => 'Pśinoski pytaś',
+'sp-contributions-suppresslog' => 'pódtłocone wužywarske pśinoski',
 'sp-contributions-username' => 'IP-adresa abo wužywarske mě:',
 'sp-contributions-toponly' => 'Jano wuše wersije pokazaś',
+'sp-contributions-newonly' => 'Jano změny pokazaś, kótarež su napóranja bokow',
 'sp-contributions-submit' => 'Pytaś',
 
 # What links here
index 37318fd..897ea5c 100644 (file)
@@ -554,10 +554,11 @@ Se l'inscrisiòun l'é stêda fâta per şbâli, es pōl scanşlêr sté mesâg.
 'resetpass-wrong-oldpass' => "Cêva 'd ingrès pruvişôria o còla 'd adès mìa vâlida.
 La cêva 'd ingrès la pré èser stêda bèle cambiêda, opór n'in pré èser stê dmandê 'na nōva pruvişôria.",
 'resetpass-recycled' => "Mèt dèinter 'na cêva 'd ingrès divêrsa da còla 'd adès.",
+'resetpass-temp-emailed' => "L'ingrès l'é stê fât cun un côdis pruvişôri. Per finîr la registrasiòun, l'é necesâri impustêr 'na nōva cêva 'd ingrès ché:",
 'resetpass-temp-password' => "Cêva 'd ingrès pruvişôria:",
 'resetpass-abort-generic' => "La mudéfica 'd la cêva 'd ingrès l'é stêda fermêda da un şlungamèint.",
 'resetpass-expired' => "La cêva 'd ingrès l'é scadûda. Mèt dèinter 'na cêva 'd ingrès nōva per fêr l'ingrès.",
-'resetpass-expired-soft' => "La tó cêva 'd ingrès l'é scadûda. T'é perghê ed siēlier 'na cêva 'd ingrès nōva o clichêr insém a scanşèla per turnêrla a mèter dèinter in sègvit.",
+'resetpass-expired-soft' => "La tó cêva 'd ingrès l'é scadûda. T'é perghê ed siēlier 'na nōva o clichêr insém a \"{{int:resetpass-submit-cancel}}\" per turnêrla a mèter dèinter in sègvit.",
 
 # Special:PasswordReset
 'passwordreset' => "Câmbia la cêva 'd ingrès",
@@ -724,7 +725,9 @@ Al tō mudéfichi în MIA incòra stêdi salvêdi.",
 'editingsection' => 'Mudéfica ed $1 (sesiòun)',
 'editingcomment' => 'Mudéfica e $1 (sesiòun nōva)',
 'editconflict' => "Cuntrâst 'd edisiòun só $1",
+'explainconflict' => "Un êter utèint l'à salvê 'na nōva versiòun ed la pàgina mèinter t'ēr adrē fêr dal mudéfichi. Int la caşèla 'd mudéfica ché 'd sōver a gh'é al tèst ed la pàgina che adès l'é in lénia, acsé cme l'é stêda salvêda da cl'êter utèint. La versiòun cun al tō mudéfichi invēci l'é int la caşèla dal mudéfichi ché sòta. S' ét vō cunfermêri, ét dēv purtêr al tō mudéfichi int al tèst che gh'é bèle (caşèla ché 'd sōver). Se té schés al ptòun '{{int:savearticle}}', a gnirà salvê '''sōl''' al tèst dèinter a la caşèla 'd mudéfica ché 'd sōver.",
 'yourtext' => 'Al tó tèst',
+'storedversion' => 'La versiòun in memôria',
 'yourdiff' => 'Diferèinsi',
 'templatesused' => '{{PLURAL:$1|Mudèl druvê|Mudē druvê}} in cla pàgina ché:',
 'template-protected' => '(prutèt)',
index 772c7f6..d43df36 100644 (file)
@@ -11,6 +11,7 @@
  * @author Aitolos
  * @author Assassingr
  * @author Astralnet
+ * @author Axil
  * @author Azimout
  * @author Badseed
  * @author Chomwitt
@@ -912,7 +913,7 @@ $2',
 
 # Change password dialog
 'changepassword' => 'Αλλαγή κωδικού',
-'resetpass_announce' => 'ΣÏ\85νδεθήκαÏ\84ε Î¼Îµ Î­Î½Î± Ï\80Ï\81οÏ\83Ï\89Ï\81ινÏ\8c ÎºÏ\89δικÏ\8c, Ï\83Ï\84αλμένο Î¼Îµ e-mail. Î\93ια Î½Î± Î¿Î»Î¿ÎºÎ»Î·Ï\81Ï\8eÏ\83εÏ\84ε Ï\84ην Ï\83Ï\8dνδεÏ\83η, Ï\80Ï\81έÏ\80ει Î½Î± Ï\83Ï\84είλεÏ\84ε Î­Î½Î± Î½Î­Î¿ ÎºÏ\89δικÏ\8c ÎµÎ´Ï\8e:',
+'resetpass_announce' => 'Για να ολοκληρώσετε την σύνδεση, πρέπει να στείλετε ένα νέο κωδικό εδώ:',
 'resetpass_text' => '<!-- Προσθέστε κείμενο εδώ -->',
 'resetpass_header' => 'Αλλαγή κωδικού πρόσβασης',
 'oldpassword' => 'Παλιός κωδικός',
@@ -928,6 +929,7 @@ $2',
 'resetpass-submit-cancel' => 'Ακύρωση',
 'resetpass-wrong-oldpass' => 'Λάθος προσωρινός ή κανονικός κωδικός.
 Μπορεί να έχετε ήδη αλλάξει επιτυχώς τον κωδικό σας ή να έχετε ζητήσει έναν νέο προσωρινό κωδικό.',
+'resetpass-recycled' => 'Παρακαλούμε επαναφέρετε τον κωδικό πρόσβασής σας σε κάτι διαφορετικό από τον τρέχοντα κωδικό πρόσβασης.',
 'resetpass-temp-password' => 'Προσωρινός κωδικός:',
 'resetpass-abort-generic' => 'Η αλλαγή του κωδικού έχει απορριφθεί από μια προέκταση.',
 
index c2906f5..efccdd9 100644 (file)
@@ -3265,6 +3265,7 @@ $1',
 'sp-contributions-newbies-sub'         => 'For new accounts',
 'sp-contributions-newbies-title'       => 'User contributions for new accounts',
 'sp-contributions-blocklog'            => 'block log',
+'sp-contributions-suppresslog'         => 'suppressed user contributions',
 'sp-contributions-deleted'             => 'deleted user contributions',
 'sp-contributions-uploads'             => 'uploads',
 'sp-contributions-logs'                => 'logs',
index d42e385..6a607c5 100644 (file)
@@ -95,6 +95,7 @@
  * @author Sethladan
  * @author Shirayuki
  * @author Spacebirdy
+ * @author Sporeunai
  * @author Stephensuleeman
  * @author Technorum
  * @author The Evil IP address
@@ -959,7 +960,7 @@ Para terminar la sesión, debes establecer una nueva contraseña aquí:',
 'resetpass-temp-password' => 'Contraseña temporal:',
 'resetpass-abort-generic' => 'Una extensión ha cancelado el cambio de la contraseña.',
 'resetpass-expired' => 'Tu contraseña ha caducado. Por favor, establece una nueva contraseña para iniciar sesión.',
-'resetpass-expired-soft' => 'Tu contraseña ha expirado y necesita ser restablecida. Elije una nueva contraseña ahora, o haz clic en cancelar para restablecerla más tarde.',
+'resetpass-expired-soft' => 'Su contraseña ha caducado y necesita reajustarse. Elija una nueva contraseña ahora, o haga clic en "{{int:resetpass-enviar-cancelar}}" para restaurarla más adelante.',
 
 # Special:PasswordReset
 'passwordreset' => 'Restablecimiento de contraseña',
@@ -1811,7 +1812,7 @@ Tu dirección de correo no se revela cuando otros usuarios te contactan.',
 'recentchanges-label-plusminus' => 'El tamaño de la página cambió esta cantidad de bytes',
 'recentchanges-legend-heading' => "'''Leyenda:'''",
 'recentchanges-legend-newpage' => '(véase también la [[Special:NewPages|lista de páginas nuevas]])',
-'rcnotefrom' => 'A continuación se muestran los cambios desde <b>$2</b> (hasta <b>$1</b>).',
+'rcnotefrom' => 'A continuación se presentan los cambios desde <strong> $2 </strong> (hasta <strong> $1 </strong> se muestra).',
 'rclistfrom' => 'Mostrar nuevos cambios desde $1',
 'rcshowhideminor' => '$1 ediciones menores',
 'rcshowhideminor-show' => 'Mostrar',
@@ -2785,6 +2786,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Esta dirección IP se encuentra actualmente bloqueada.
 A continuación se muestra la última entrada del registro de bloqueos para mayor referencia.',
 'sp-contributions-search' => 'Buscar contribuciones',
+'sp-contributions-suppresslog' => 'Contribuciones borradas de usuario',
 'sp-contributions-username' => 'Dirección IP o nombre de usuario:',
 'sp-contributions-toponly' => 'Solo mostrar últimas ediciones de página',
 'sp-contributions-newonly' => 'Mostrar solo ediciones que son creaciones de páginas',
index e7bf3ae..b145235 100644 (file)
@@ -873,7 +873,7 @@ Et sisselogimine lõpule viia, pead määrama siin uue parooli:',
 'resetpass-temp-password' => 'Ajutine parool:',
 'resetpass-abort-generic' => 'Tarkvaralisa on paroolimuudatuse abortinud.',
 'resetpass-expired' => 'Sinu parool on iganenud. Palun määra uus parool, et sisse logida.',
-'resetpass-expired-soft' => 'Sinu parool on iganenud ja tuleb uuesti määrata. Palun vali kohe uus parool või klõpsa "Loobu", et määrata see hiljem.',
+'resetpass-expired-soft' => 'Sinu parool on iganenud ja tuleb uuesti määrata. Palun vali kohe uus parool või klõpsa "{{int:resetpass-submit-cancel}}", et määrata see hiljem.',
 
 # Special:PasswordReset
 'passwordreset' => 'Parooli lähtestamine',
@@ -1718,14 +1718,26 @@ See teave on avalik.',
 'recentchanges-label-unpatrolled' => 'Seda muudatust ei ole veel kontrollitud',
 'recentchanges-label-plusminus' => 'Lehekülje suuruse muutus baitides',
 'recentchanges-legend-newpage' => '(vaata ka [[Special:NewPages|uute lehekülgede loendit]])',
-'rcnotefrom' => "Allpool on toodud muudatused alates: '''$2''' (näidatakse kuni '''$1''' muudatust)",
+'rcnotefrom' => 'Allpool on toodud muudatused alates: <strong>$2</strong> (näidatakse kuni <strong>$1</strong> muudatust)',
 'rclistfrom' => 'Näita muudatusi alates: $1',
 'rcshowhideminor' => 'Pisiparandused ($1)',
+'rcshowhideminor-show' => 'näita',
+'rcshowhideminor-hide' => 'peida',
 'rcshowhidebots' => 'Robotid ($1)',
+'rcshowhidebots-show' => 'näita',
+'rcshowhidebots-hide' => 'peida',
 'rcshowhideliu' => 'Registreeritud kasutajad ($1)',
+'rcshowhideliu-show' => 'näita',
+'rcshowhideliu-hide' => 'peida',
 'rcshowhideanons' => 'Anonüümsed kasutajad ($1)',
+'rcshowhideanons-show' => 'näita',
+'rcshowhideanons-hide' => 'peida',
 'rcshowhidepatr' => 'Kontrollitud muudatused ($1)',
+'rcshowhidepatr-show' => 'näita',
+'rcshowhidepatr-hide' => 'peida',
 'rcshowhidemine' => 'Minu parandused ($1)',
+'rcshowhidemine-show' => 'näita',
+'rcshowhidemine-hide' => 'peida',
 'rclinks' => 'Näita viimast $1 muudatust viimase $2 päeva jooksul<br />$3',
 'diff' => 'erin',
 'hist' => 'ajal',
@@ -1855,6 +1867,7 @@ Enne kui jätkad uuesti üleslaadimisega, peaksid paluma olukorda hinnata kellel
 'php-uploaddisabledtext' => 'Failide üleslaadmine on PHP seadetes keelatud.
 Palun vaata <code>file_uploads</code> sätet.',
 'uploadscripted' => 'See fail sisaldab HTML- või skriptikoodi, mida veebilehitseja võib valesti kuvada.',
+'uploadscriptednamespace' => 'See SVG-fail sisaldab keelatud nimeruumi "$1".',
 'uploadinvalidxml' => 'Üleslaaditud failis sisalduvat XMLi ei õnnestunud liigendada.',
 'uploadvirus' => 'Fail sisaldab viirust! Täpsemalt: $1',
 'uploadjava' => 'See fail on ZIP-fail, milles on Java .class-fail.
@@ -2661,8 +2674,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'See IP-aadress on parajasti blokeeritud.
 Allpool on toodud viimane blokeerimislogi sissekanne:',
 'sp-contributions-search' => 'Kaastöö otsimine',
+'sp-contributions-suppresslog' => 'varjatud kaastöö',
 'sp-contributions-username' => 'IP-aadress või kasutajanimi:',
 'sp-contributions-toponly' => 'Ainult uusimad redaktsioonid',
+'sp-contributions-newonly' => 'Näita ainult uute lehekülgedega alustamist',
 'sp-contributions-submit' => 'Otsi',
 
 # What links here
index a4bce8e..d33a51a 100644 (file)
@@ -15,6 +15,7 @@
  * @author Asoxor
  * @author Baqeri
  * @author Behdarvandyani
+ * @author Calak
  * @author Dalba
  * @author E THP
  * @author Ebraminio
@@ -454,7 +455,7 @@ $imageFiles = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'پیوند خط کشی شده در زیر:',
+'tog-underline' => 'خط کشیدن زیر پیوندها:',
 'tog-hideminor' => 'تغییرات جزئی از فهرست تغییرات اخیر پنهان شوند',
 'tog-hidepatrolled' => 'ویرایش‌های گشت‌خورده از فهرست تغییرات اخیر پنهان شوند',
 'tog-newpageshidepatrolled' => 'صفحه‌های گشت‌خورده از فهرست صفحه‌های تازه پنهان شوند',
@@ -908,7 +909,7 @@ $2',
 'userlogin-resetpassword-link' => 'گذرواژه‌تان را فراموش کردید؟',
 'helplogin-url' => 'Help:ورود به سامانه',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|راهنمای ورود به سامانه]]',
-'userlogin-loggedin' => 'Ø´Ù\85ا Ø¯Ø± Ø­Ø§Ù\84 Ø­Ø§Ø¶Ø± Ø¨Ù\87â\80\8cعÙ\86Ù\88اÙ\86 {{GENDER:$1|$1}} Ù\88ارد Ø³Û\8cستÙ\85 Ø´Ø¯Ù\87â\80\8cاÛ\8cد.
+'userlogin-loggedin' => 'شما در حال حاضر به‌عنوان {{GENDER:$1|$1}} وارد شده‌اید.
 از فرم پایین برای ورود به‌عنوان یک کاربر دیگر استفاده کنید.',
 'userlogin-createanother' => 'ایجاد یک حساب کاربری دیگر',
 'createacct-join' => 'اطلاعاتتان را در زیر وارد کنید',
@@ -917,7 +918,7 @@ $2',
 'createacct-emailoptional' => 'نشانی رایانامه (اختیاری)',
 'createacct-email-ph' => 'نشانی رایانامه را وارد کنید',
 'createacct-another-email-ph' => 'نشانی رایانامه را وارد کنید',
-'createaccountmail' => 'استÙ\81ادÙ\87 Ø§Ø² Ø±Ù\85ز Ø¹Ø¨Ù\88ر Ù\85Ù\88Ù\82ت ØªØµØ§Ø¯Ù\81Û\8c Ù\88 Ù\81رستادÙ\86 Ø¢Ù\86 Ø¨Ù\87 Ù\86شاÙ\86Û\8c Ø§Û\8cÙ\85Û\8cÙ\84 مشخص‌شده',
+'createaccountmail' => 'استÙ\81ادÙ\87 Ø§Ø² Ø±Ù\85ز Ø¹Ø¨Ù\88ر Ù\85Ù\88Ù\82ت ØªØµØ§Ø¯Ù\81Û\8c Ù\88 Ù\81رستادÙ\86 Ø¢Ù\86 Ø¨Ù\87 Ù\86شاÙ\86Û\8c Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87 مشخص‌شده',
 'createacct-realname' => 'نام واقعی (اختیاری)',
 'createaccountreason' => 'دلیل:',
 'createacct-reason' => 'دلیل',
@@ -1001,7 +1002,7 @@ $2',
 'usernamehasherror' => 'نام کاربری نمی‌تواند شامل نویسه‌های درهم باشد',
 'login-throttled' => 'شما به تازگی چندین‌بار برای ثبت ورود تلاش کرده‌اید.
 لطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.',
-'login-abort-generic' => 'ورود شما به سیستم ناموفق بود - خاتمهٔ ناگهانی داده شد',
+'login-abort-generic' => 'ورود شما ناموفق بود - خاتمهٔ ناگهانی داده شد',
 'loginlanguagelabel' => 'زبان: $1',
 'suspicious-userlogout' => 'درخواست شما برای خروج از سامانه رد شد زیرا به نظر می‌رسد که این درخواست توسط یک مرورگر معیوب یا پروکسی میانگیر ارسال شده باشد.',
 'createacct-another-realname-tip' => 'نام واقعی اختیاری است.
@@ -1017,7 +1018,7 @@ $2',
 
 # Change password dialog
 'changepassword' => 'تغییر گذرواژه',
-'resetpass_announce' => 'شما باید برای پایان ورود به سیستم،رمز عبور جدیدی را تنظیم کنید.',
+'resetpass_announce' => 'شما باید برای پایان ورود به سامانه، گذرواژهٔ جدیدی را تنظیم کنید.',
 'resetpass_text' => '<!-- اینجا متن اضافه کنید -->',
 'resetpass_header' => 'تغییر گذرواژهٔ حساب کاربری',
 'oldpassword' => 'گذرواژهٔ پیشین:',
@@ -1039,7 +1040,7 @@ $2',
 'resetpass-temp-password' => 'گذرواژهٔ موقت:',
 'resetpass-abort-generic' => 'تغییر گذرواژه به دست یکی از افزونه‌ها لغو شده است.',
 'resetpass-expired' => 'رمز عبور شما منقضی شده‌است. لطفاً برای ورود رمز عبور جدیدی را تنظیم کنید.',
-'resetpass-expired-soft' => 'رمز عبور شما منقضی شده‌است، و نیاز به تنظیم مجدد دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تنظیم مجدد آن بعدآً، دکمهٔ لغو را کلیک کنید.',
+'resetpass-expired-soft' => 'رمز عبور شما منقضی شده‌است، و نیاز به تنظیم مجدد دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تنظیم مجدد آن بعدآً، دکمه "{{int:resetpass-submit-cancel}}" را کلیک کنید.',
 
 # Special:PasswordReset
 'passwordreset' => 'بازنشانی گذرواژه',
@@ -1205,8 +1206,8 @@ $2
 *'''گوگل کروم:'''کلیدهای ''Ctrl+Shift+R'' را با هم فشار دهید. (در رایانه‌های اپل مکینتاش کلید‌های ''⌘-Shift-R'')
 *'''اینترنت اکسپلورر:''' کلید ''Ctrl'' را نگه‌دارید و روی دکمهٔ ''Refresh'' کلیک کنید، یا کلید‌های ''Ctrl-F5'' را با هم فشار دهید
 *'''اپرا:''' حافظهٔ نهانی مرورگر را از طریق منوی ''Tools &rarr; Preferences'' پاک کنید",
-'usercssyoucanpreview' => "'''Ù\86کتÙ\87:''' Ù¾Û\8cØ´ Ø§Ø² Ø°Ø®Û\8cرÙ\87â\80\8cکردÙ\86 Ù\81اÛ\8cÙ\84 سی‌اس‌اس خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
-'userjsyoucanpreview' => "'''Ù\86کتÙ\87:''' Ù¾Û\8cØ´ Ø§Ø² Ø°Ø®Û\8cرÙ\87â\80\8cکردÙ\86 Ù\81اÛ\8cÙ\84 جاوااسکریپت خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
+'usercssyoucanpreview' => "'''Ù\86کتÙ\87:''' Ù¾Û\8cØ´ Ø§Ø² Ø°Ø®Û\8cرÙ\87â\80\8cکردÙ\86 Ù¾Ø±Ù\88Ù\86دÙ\87 سی‌اس‌اس خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
+'userjsyoucanpreview' => "'''Ù\86کتÙ\87:''' Ù¾Û\8cØ´ Ø§Ø² Ø°Ø®Û\8cرÙ\87â\80\8cکردÙ\86 Ù¾Ø±Ù\88Ù\86دÙ\87Ù\94 جاوااسکریپت خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
 'usercsspreview' => "'''فراموش مکنید که شما فقط دارید پیش‌نمایش سی‌اس‌اس کاربری‌تان را می‌بینید.'''
 '''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
 'userjspreview' => "'''به یاد داشته باشید که شما فقط دارید جاوااسکریپت کاربری‌تان را امتحان می‌کنید/پیش‌نمایش آن را می‌بینید.'''
@@ -1226,7 +1227,7 @@ $2
 'session_fail_preview' => "'''شرمنده! به علت از دست رفتن اطلاعات نشست کاربری نمی‌توانیم ویرایش شما را پردازش کنیم.'''
 لطفاً دوباره سعی کنید.
 اگر دوباره به همین پیام برخوردید از سامانه [[Special:UserLogout|خارج شوید]] و دوباره وارد شوید.",
-'session_fail_preview_html' => "'''Ù\85تاسفانه امکان ثبت ویرایش شما به خاطر از دست رفتن اطلاعات نشست کاربری وجود ندارد.'''
+'session_fail_preview_html' => "'''Ù\85تأسفانه امکان ثبت ویرایش شما به خاطر از دست رفتن اطلاعات نشست کاربری وجود ندارد.'''
 
 ''با توجه به این که در {{SITENAME}} امکان درج اچ‌تی‌ام‌ال خام فعال است، پیش‌نمایش صفحه پنهان شده تا امکان حملات مبتنی بر جاوااسکریپت وجود نداشته باشد.''
 
@@ -1309,8 +1310,8 @@ $2
 'content-failed-to-parse' => 'عدم موفقیت در تجزیه محتوای $2 برای مدل $1: $3',
 'invalid-content-data' => 'داده محتوای نامعتبر',
 'content-not-allowed-here' => 'محتوای «$1» در صفحهٔ [[$2]] مجاز نیست',
-'editwarning-warning' => 'خروج از این صفحه ممکن است باعث شود که شما هر شانسی که به وجود آورده اید را از دست بدهید.
-اگر شما وارد سیستم شده‌اید، می‌توانید این هشدار را در بخش «در حال ویرایش» ترجیحاتتان غیرفعال کنید.',
+'editwarning-warning' => 'خروج از این صفحه ممکن است باعث شود که شما هر شانسی که به وجود آوردهاید را از دست بدهید.
+اگر شما وارد سامانه شده‌اید، می‌توانید این هشدار را در بخش «{{int:prefs-editing}}» ترجیحاتتان غیرفعال کنید.',
 'editpage-notsupportedcontentformat-title' => 'فرمت محتوا پشتیبانی نشده',
 'editpage-notsupportedcontentformat-text' => 'فرمت محتوای $1 توسط مدل محتوای $2 پشتیبانی نشده‌است.',
 
@@ -1895,7 +1896,7 @@ $1",
 'recentchanges-legend-heading' => "'''اختصارها:'''",
 'recentchanges-legend-newpage' => '(همچنین به [[Special:NewPages|فهرست صفحات جدید]] نگاه کنید)',
 'recentchanges-legend-plusminus' => "('' ±۱۲۳'')",
-'rcnotefrom' => 'در زیر تغییرات از تاریخ <b>$2</b> آمده‌اند (تا <b>$1</b> مورد نشان داده می‌شود).',
+'rcnotefrom' => 'در زیر تغییرات از <strong>$2</strong> (تا <strong>$1</strong> نشان داده شده‌است).',
 'rclistfrom' => 'نمایش تغییرات جدید با شروع از $1',
 'rcshowhideminor' => '$1 ویرایش‌های جزئی',
 'rcshowhideminor-show' => 'نمایش',
@@ -1903,7 +1904,7 @@ $1",
 'rcshowhidebots' => '$1 ربات‌ها',
 'rcshowhidebots-show' => 'نمایش',
 'rcshowhidebots-hide' => 'پنهان کردن',
-'rcshowhideliu' => 'کاربران نسخهٔ $1 ثبت‌نام‌ کردند',
+'rcshowhideliu' => '$1 کاربران ثبت‌نام‌کردە',
 'rcshowhideliu-show' => 'نمایش',
 'rcshowhideliu-hide' => 'پنهان کردن',
 'rcshowhideanons' => '$1 کاربران ناشناس',
@@ -2035,8 +2036,8 @@ $1",
 'file-exists-duplicate' => 'به نظر می‌رسد این پرونده نسخه‌ای تکراری از {{PLURAL:$1|پروندهٔ|پرونده‌های}} زیر باشد:',
 'file-deleted-duplicate' => 'یک پرونده نظیر این پرونده ([[:$1]]) قبلاً حذف شده‌است.
 شما باید تاریخچهٔ حذف آن پرونده را قبل از بارگذاری مجدد آن ببینید.',
-'file-deleted-duplicate-notitle' => 'یک پرونده یکسان بااین پرونده قبلا حذف شده است و عنوان متوقف شده‌است.
-Ø´Ù\85ا Ø¨Ø§Û\8cد Ø§Ø² Ú©Ø³Û\8c Ú©Ù\87 Ø¯Ø³ØªØ±Ø³Û\8c Ù\85شاÙ\87دÙ\87Ù\94 Ù\81اÛ\8cÙ\84 متوقف شده را دارد، درخواست کنید تا شرایط را قبل از بارگذاری مجدد بررسی کند.',
+'file-deleted-duplicate-notitle' => 'یک پرونده یکسان بااین پرونده قبلاً حذف شده است و عنوان متوقف شده‌است.
+Ø´Ù\85ا Ø¨Ø§Û\8cد Ø§Ø² Ú©Ø³Û\8c Ú©Ù\87 Ø¯Ø³ØªØ±Ø³Û\8c Ù\85شاÙ\87دÙ\87Ù\94 Ù¾Ø±Ù\88Ù\86دÙ\87 متوقف شده را دارد، درخواست کنید تا شرایط را قبل از بارگذاری مجدد بررسی کند.',
 'uploadwarning' => 'هشدار بارگذاری',
 'uploadwarning-text' => 'لطفاً توضیحات پرونده را در زیر تغییر دهید و دوباره تلاش کنید.',
 'savefile' => 'ذخیرهٔ پرونده',
@@ -2253,7 +2254,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 'shared-repo-from' => 'از $1',
 'shared-repo' => 'یک مخزن مشترک',
 'shared-repo-name-wikimediacommons' => 'ویکی‌انبار',
-'upload-disallowed-here' => 'Ù\85تاسÙ\81اÙ\86Ù\87 Ø´Ù\85ا Ù\86Ù\85Û\8c توانید این پرونده را بازنویس کنید.',
+'upload-disallowed-here' => 'Ù\85تأسÙ\81اÙ\86Ù\87 Ø´Ù\85ا Ù\86Ù\85Û\8câ\80\8cتوانید این پرونده را بازنویس کنید.',
 
 # File reversion
 'filerevert' => 'واگردانی $1',
@@ -2647,7 +2648,7 @@ $PAGEINTRO $NEWPAGE
 نامه: $PAGEEDITOR_EMAIL
 ویکی: $PAGEEDITOR_WIKI
 
-تا هنگامی که به صفحه سر نزده‌اید، در صورت رخ‌دادنِ احتمالیِ فعالیت بیشتر، تا زمانی که در با کاربریتان در سیستم هستید، اعلانیه‌ای برای شما فرستاده نخواهد شد.
+تا هنگامی که به صفحه سر نزده‌اید، در صورت رخ‌دادنِ احتمالیِ فعالیت بیشتر، تا زمانی که در با کاربریتان در سامانه هستید، اعلانیه‌ای برای شما فرستاده نخواهد شد.
 شما همچنین می‌توانید در صفحهٔ پی‌گیری‌های خود پرچم‌های مربوط به آگاهی‌رسانی را صفر کنید همچنین می‌توانید پرچم‌های آگاهی‌سازی را بازنشانی کنید.
 
 دوستدار شما، سامانهٔ آگاهی‌رسانی {{SITENAME}}
@@ -2882,6 +2883,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'این نشانی آی‌پی در حال حاضر بسته است.
 آخرین سیاههٔ بسته شدن در زیر آمده‌است:',
 'sp-contributions-search' => 'جستجوی مشارکت‌ها',
+'sp-contributions-suppresslog' => 'کمک‌های کاربر متوقف شده',
 'sp-contributions-username' => 'نشانی آی‌پی یا نام کاربری:',
 'sp-contributions-toponly' => 'فقط ویرایش‌هایی که آخرین نسخه‌اند نمایش داده شود',
 'sp-contributions-newonly' => 'فقط نمایش ویرایش‌هایی که تولید‌های صفحه هستند',
@@ -3374,7 +3376,7 @@ $2',
 
 # Info page
 'pageinfo-title' => 'اطلاعات در مورد «$1»',
-'pageinfo-not-current' => 'Ù\85تاسفانه تهیه اطلاعات ویرایش‌های قدیمی غیرممکن است.',
+'pageinfo-not-current' => 'Ù\85تأسفانه تهیه اطلاعات ویرایش‌های قدیمی غیرممکن است.',
 'pageinfo-header-basic' => 'اطلاعات اولیه',
 'pageinfo-header-edits' => 'ویرایش تاریخچه',
 'pageinfo-header-restrictions' => 'حفاظت از صفحه',
@@ -4364,7 +4366,7 @@ $5
 'logentry-newusers-newusers' => 'حساب کاربری $1 {{GENDER:$2|ایجاد شد}}',
 'logentry-newusers-create' => 'حساب کاربری $1 {{GENDER:$2|ایجاد شد}}',
 'logentry-newusers-create2' => 'حساب کاربری $3 توسط $1 {{GENDER:$2|ایجاد شد}}',
-'logentry-newusers-byemail' => 'حساب کاربری  $3  توسط $1 {{GENDER:$2|ایجاد شد}} و رمز عبور به وسیلهٔ ایمیل ارسال شد',
+'logentry-newusers-byemail' => 'حساب کاربری $3 توسط $1 {{GENDER:$2|ایجاد شد}} و رمز عبور به‌وسیلهٔ رایانامه ارسال شد',
 'logentry-newusers-autocreate' => 'حساب $1  به شکل خودکار {{GENDER:$2|ایجاد شد}}',
 'logentry-rights-rights' => '$1 عضویت $3 را از گروه $4 به $5 {{GENDER:$2|تغییر داد}}',
 'logentry-rights-rights-legacy' => '$1 گروه عضویت $3 را {{GENDER:$2|تغییر داد}}',
index 02f059a..fe968f7 100644 (file)
@@ -886,7 +886,7 @@ Jotta pääset kirjautumaan sisään kunnolla, sinun on nyt asetettava uusi sala
 'resetpass-temp-password' => 'Väliaikainen salasana:',
 'resetpass-abort-generic' => 'Laajennus keskeytti salasanan vaihdon.',
 'resetpass-expired' => 'Salasanasi on vanhentunut. Valitse uusi salasana, jotta pääset kirjautumaan sisään.',
-'resetpass-expired-soft' => 'Salasanasi on vanhentunut ja se pitää uudistaa. Valitse nyt uusi salasana tai peruuta toiminto, niin voit uudistaa salasanan myöhemmin.',
+'resetpass-expired-soft' => 'Salasanasi on vanhentunut ja se pitää uudistaa. Valitse uusi salasana nyt tai paina "{{int:resetpass-submit-cancel}}", niin voit uudistaa salasanan myöhemmin.',
 
 # Special:PasswordReset
 'passwordreset' => 'Salasanan uudistus',
@@ -1862,7 +1862,7 @@ Sinun on syytä pyytää jotakuta häivytettyjen tietojen näkemiseen oikeutettu
 'uploaddisabledtext' => 'Tiedostojen tallennus on poistettu käytöstä.',
 'php-uploaddisabledtext' => 'PHP:n tiedostojen lähetys ei ole käytössä. Tarkista asetukset kohdasta file_uploads.',
 'uploadscripted' => 'Tämä tiedosto sisältää HTML-koodia tai skriptejä, jotka selain saattaa virheellisesti suorittaa.',
-'uploadscriptednamespace' => "Tämä SVG-tiedosto sisältää kelvottoman nimiavaruuden '$1'",
+'uploadscriptednamespace' => 'Tämä SVG-tiedosto sisältää nimiavaruuden ”$1”, joka ei ole sallittu.',
 'uploadinvalidxml' => 'Ladatun tiedoston XML-koodia ei voitu jäsentää kunnolla.',
 'uploadvirus' => 'Tiedosto sisältää viruksen. Tarkemmat tiedot: $1',
 'uploadjava' => 'Tämä tiedosto on ZIP-tiedosto, joka sisältää Java .class-tiedoston.
@@ -2676,6 +2676,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Tämä IP-osoite on tällä hetkellä estetty.
 Alla on viimeisin estolokin tapahtuma:',
 'sp-contributions-search' => 'Etsi muokkauksia',
+'sp-contributions-suppresslog' => 'häivytetyt käyttäjän muokkaukset',
 'sp-contributions-username' => 'IP-osoite tai käyttäjätunnus',
 'sp-contributions-toponly' => 'Näytä vain muokkaukset, jotka ovat viimeisimpiä versioita',
 'sp-contributions-newonly' => 'Näytä vain muokkaukset, joilla on luotu sivu',
@@ -3027,6 +3028,7 @@ Tallenna tiedot koneellesi ja tuo ne tällä sivulla.',
 'import-error-special' => 'Sivua $1 ei tuotu, koska se kuuluu erityiseen nimiavaruuteen, joka ei salli sivuja.',
 'import-error-invalid' => 'Sivua $1 ei tuotu, koska sen nimi ei kelpaa.',
 'import-error-unserialize' => 'Versiota $2 sivusta $1 ei voida jakaa osiin. Version ilmoitettiin käyttävän sisältömallia $3 ja sarjoitusmuotoilua $4.',
+'import-error-bad-location' => 'Sivun versiota $2, joka käyttää sisällön mallia $3, ei voi tallettaa kohteeseen "$1" tässä wikissä, koska tuota mallia ei tueta kyseisellä sivulla.',
 'import-options-wrong' => '{{PLURAL:$2|Väärä asetus|Väärät asetukset}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Annettu perussivun nimi ei kelpaa.',
 'import-rootpage-nosubpage' => 'Annetun perussivun nimiavaruus "$1" ei salli alasivuja.',
index 0107d8f..fa39b60 100644 (file)
@@ -78,6 +78,7 @@
  * @author Nobody
  * @author Od1n
  * @author Omnipaedista
+ * @author Orlodrim
  * @author Peter17
  * @author PieRRoMaN
  * @author ProgVal
@@ -421,11 +422,11 @@ $separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Lien hypertexte:',
+'tog-underline' => 'Souligner les liens :',
 'tog-hideminor' => 'Masquer les modifications mineures dans les changements récents',
-'tog-hidepatrolled' => 'Masquer les modifications surveillées dans les changements récents',
+'tog-hidepatrolled' => 'Masquer les modifications surveillées dans les modifications récentes',
 'tog-newpageshidepatrolled' => 'Masquer les pages surveillées dans la liste des nouvelles pages',
-'tog-extendwatchlist' => 'Développer la liste de suivi pour voir tous les changements, non seulement le plus récent',
+'tog-extendwatchlist' => 'Étendre la liste de suivi pour afficher toutes les modifications et pas uniquement les plus récentes',
 'tog-usenewrc' => 'Grouper les changements par page dans les modifications récentes et la liste de suivi (nécessite JavaScript)',
 'tog-numberheadings' => 'Numéroter automatiquement les titres de section',
 'tog-showtoolbar' => "Afficher la barre d'outils de modification (nécessite JavaScript)",
@@ -434,9 +435,9 @@ $messages = array(
 'tog-rememberpassword' => 'Me reconnecter automatiquement lors des prochaines visites avec ce navigateur (au maximum $1&nbsp;{{PLURAL:$1|jour|jours}})',
 'tog-watchcreations' => "Ajouter les pages que je crée et les fichiers que j'importe à ma liste de suivi",
 'tog-watchdefault' => 'Ajouter les pages et les fichiers que je modifie à ma liste de suivi',
-'tog-watchmoves' => 'Ajouter les pages et les fichiers que je déplace à ma liste de suivi',
+'tog-watchmoves' => 'Ajouter les pages et les fichiers que je renomme à ma liste de suivi',
 'tog-watchdeletion' => 'Ajouter les pages et les fichiers que je supprime à ma liste de suivi',
-'tog-minordefault' => 'Marquer toutes les modifications mineures par défaut',
+'tog-minordefault' => 'Marquer toutes mes modifications comme mineures par défaut',
 'tog-previewontop' => 'Afficher la prévisualisation au-dessus de la zone de modification',
 'tog-previewonfirst' => 'Afficher la prévisualisation lors de la première modification',
 'tog-enotifwatchlistpages' => "M'avertir par courriel lorsqu'une page ou un fichier de ma liste de suivi est modifiée",
@@ -464,23 +465,23 @@ $messages = array(
 
 'underline-always' => 'Toujours',
 'underline-never' => 'Jamais',
-'underline-default' => 'Navigateur ou thème par défaut',
+'underline-default' => 'Valeur par défaut du navigateur ou du thème',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Style de police de la zone de modification :',
-'editfont-default' => 'Navigateur par défaut',
-'editfont-monospace' => 'Police Monospaced',
-'editfont-sansserif' => 'Police Sans-serif',
-'editfont-serif' => 'Police Serif',
+'editfont-default' => 'Police par défaut du navigateur',
+'editfont-monospace' => 'Police à chasse fixe',
+'editfont-sansserif' => 'Police sans-serif',
+'editfont-serif' => 'Police serif',
 
 # Dates
-'sunday' => 'Dimanche',
-'monday' => 'Lundi',
-'tuesday' => 'Mardi',
-'wednesday' => 'Mercredi',
-'thursday' => 'Jeudi',
-'friday' => 'Vendredi',
-'saturday' => 'Samedi',
+'sunday' => 'dimanche',
+'monday' => 'lundi',
+'tuesday' => 'mardi',
+'wednesday' => 'mercredi',
+'thursday' => 'jeudi',
+'friday' => 'vendredi',
+'saturday' => 'samedi',
 'sun' => 'Dim.',
 'mon' => 'Lun.',
 'tue' => 'Mar.',
@@ -992,7 +993,7 @@ Pour terminer la connexion, vous devez fournir un nouveau mot de passe ici :',
 'resetpass-temp-password' => 'Mot de passe temporaire :',
 'resetpass-abort-generic' => 'La modification du mot de passe a été annulée par une extension.',
 'resetpass-expired' => 'Votre mot de passe a expiré. Veuillez en fournir un nouveau pour vous connecter.',
-'resetpass-expired-soft' => 'Votre mot de passe a expiré, et doit être réinitialisé. Veuillez en choisir un nouveau maintenant, ou cliquer sur annuler pour le faire plus tard.',
+'resetpass-expired-soft' => 'Votre mot de passe a expiré, et doit être réinitialisé. Veuillez en choisir un nouveau maintenant, ou cliquer sur « {{int:resetpass-submit-cancel}} » pour le faire plus tard.',
 
 # Special:PasswordReset
 'passwordreset' => 'Remise à zéro du mot de passe',
@@ -2351,7 +2352,7 @@ Les entrées <del>barrées</del> ont été résolues.',
 'deadendpagestext' => "Les pages suivantes ne contiennent aucun lien vers d'autres pages du wiki.",
 'protectedpages' => 'Pages protégées',
 'protectedpages-indef' => 'Uniquement les protections permanentes',
-'protectedpages-summary' => 'Cette page liste les pages existantes actuellement protégées. Pour une liste des titres protégés depuis leur création, voir [[{{#special:ProtectedTitles}}]].',
+'protectedpages-summary' => 'Cette page liste les pages existantes actuellement protégées. Pour une liste des titres protégés contre la création, voir [[{{#special:ProtectedTitles}}]].',
 'protectedpages-cascade' => 'Uniquement les protections en cascade',
 'protectedpages-noredirect' => 'Masquer les redirections',
 'protectedpagesempty' => "Aucune page n'est protégée de cette façon.",
@@ -2364,7 +2365,7 @@ Les entrées <del>barrées</del> ont été résolues.',
 'protectedpages-unknown-timestamp' => 'Inconnu',
 'protectedpages-unknown-performer' => 'Utilisateur inconnu',
 'protectedtitles' => 'Titres protégés',
-'protectedtitles-summary' => 'Cette page liste les titres actuellement protégés depuis leur création. Pour une liste des pages  protégées existantes, voir [[{{#special:ProtectedPages}}]].',
+'protectedtitles-summary' => 'Cette page liste les titres actuellement protégés contre la création. Pour une liste des pages protégées existantes, voir [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty' => "Aucun titre n'est actuellement protégé avec ces paramètres.",
 'listusers' => 'Liste des utilisateurs',
 'listusers-editsonly' => 'Ne montrer que les utilisateurs ayant au moins une contribution',
@@ -2820,6 +2821,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => "Cette adresse IP est actuellement bloquée.
 La dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
 'sp-contributions-search' => 'Rechercher les contributions',
+'sp-contributions-suppresslog' => 'contributions des utilisateurs supprimées',
 'sp-contributions-username' => "Adresse IP ou nom d'utilisateur :",
 'sp-contributions-toponly' => 'Ne montrer que les contributions qui sont les dernières des articles',
 'sp-contributions-newonly' => 'Afficher uniquement les modifications qui sont des créations de page',
index a11e965..6530ba3 100644 (file)
@@ -522,7 +522,7 @@ $messages = array(
 'articlepage' => 'Vêde la pâge de contegnu',
 'talk' => 'Discussion',
 'views' => 'Vues',
-'toolbox' => 'Bouèta d’outils',
+'toolbox' => 'Outils',
 'userpage' => 'Vêde la pâge utilisator',
 'projectpage' => 'Vêde la pâge projèt',
 'imagepage' => 'Vêde la pâge du fichiér',
@@ -805,7 +805,7 @@ Se vos plét, tornâd èprovar.',
 'passwordtooshort' => 'Voutron contresegno dêt contegnir por lo muens $1 caractèro{{PLURAL:$1||s}}.',
 'password-name-match' => 'Voutron contresegno dêt étre difèrent de voutron nom d’utilisator.',
 'password-login-forbidden' => 'L’usâjo de cél nom d’utilisator et de cél contresegno est étâ dèfendu.',
-'mailmypassword' => 'Recêvre un contresegno novél per mèssageria èlèctronica',
+'mailmypassword' => 'Rebetar a zérô lo contresegno',
 'passwordremindertitle' => 'Contresegno temporèro novél por {{SITENAME}}',
 'passwordremindertext' => 'Yon (probâblament vos, dês l’adrèce IP $1) at demandâ un contresegno
 novél por {{SITENAME}} ($4). Un contresegno temporèro est étâ fêt por
@@ -1715,7 +1715,7 @@ Se vos chouèsésséd de lo balyér, serat empleyê por vos atribuar voutres ôv
 'rc_categories_any' => 'Totes',
 'rc-change-size-new' => '$1 octèt{{PLURAL:$1||s}} aprés changement',
 'newsectionsummary' => '/* $1 */ novèla sèccion',
-'rc-enhanced-expand' => 'Montrar los dètalys (at fôta de JavaScript)',
+'rc-enhanced-expand' => 'Fâre vêre los dètalys',
 'rc-enhanced-hide' => 'Cachiér los dètalys',
 'rc-old-title' => 'fêta avouéc lo titro originâl « $1 »',
 
@@ -2632,9 +2632,9 @@ $1',
 'contributions' => 'Contribucions de l’utilisat{{GENDER:$1|or|rice}}',
 'contributions-title' => 'Lista de les contribucions a l’usanciér $1',
 'mycontris' => 'Contribucions',
-'contribsub2' => 'Por $1 ($2)',
+'contribsub2' => 'Por {{GENDER:$3|$1}} ($2)',
 'nocontribs' => 'Y at gins de changement que corrèspond a cetos critèros.',
-'uctop' => '(dèrriére)',
+'uctop' => '(d’ora)',
 'month' => 'Dês lo mês (et devant) :',
 'year' => 'Dês l’an (et devant) :',
 
@@ -3234,7 +3234,7 @@ Se vos l’ègzécutâd, voutron sistèmo pôt étre compromês.",
 'file-nohires' => 'Gins de rèsolucion ples hôta disponibla.',
 'svg-long-desc' => 'Fichiér SVG, rèsolucion de $1 × $2 pixèls, talye : $3',
 'svg-long-error' => 'Fichiér SVG envalido : $1',
-'show-big-image' => 'Émâge en rèsolucion ples hôta',
+'show-big-image' => 'Fichiér d’origina',
 'show-big-image-preview' => 'Talye de ceti apèrçu : $1.',
 'show-big-image-other' => '{{PLURAL:$2|Ôtra rèsolucion|Ôtres rèsolucions}} : $1.',
 'show-big-image-size' => '$1 × $2 pixèls',
index c131377..c867620 100644 (file)
@@ -363,7 +363,7 @@ $messages = array(
 'postcomment' => 'નવો વિભાગ',
 'articlepage' => 'લેખનું પાનું જુઓ',
 'talk' => 'ચર્ચા',
-'views' => 'દેખાવ',
+'views' => 'દેખાવ',
 'toolbox' => 'સાધનો',
 'userpage' => 'સભ્યનું પાનું જુઓ',
 'projectpage' => 'પ્રકલ્પનું પાનું જુઓ',
@@ -434,7 +434,7 @@ $1',
 'viewsourceold' => 'સ્રોત જુઓ',
 'editlink' => 'ફેરફાર',
 'viewsourcelink' => 'સ્રોત જુઓ',
-'editsectionhint' => 'ફà«\87રફાર àª\95રà«\8b - àªªàª°àª¿àª\9aà«\8dàª\9bà«\87દ: $1',
+'editsectionhint' => 'પરિàª\9aà«\8dàª\9bà«\87દ àª«à«\87રફાર àª\95રà«\8b: $1',
 'toc' => 'અનુક્રમણિકા',
 'showtoc' => 'બતાવો',
 'hidetoc' => 'છુપાવો',
@@ -455,7 +455,7 @@ $1',
 'sort-ascending' => 'ચડતા ક્રમમાં ગોઠવો',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
-'nstab-main' => 'લà«\87àª\96',
+'nstab-main' => 'પાનà«\81àª\82',
 'nstab-user' => 'સભ્ય પાનું',
 'nstab-media' => 'મિડીયા પાનું',
 'nstab-special' => 'ખાસ પાનું',
@@ -702,6 +702,9 @@ $2',
 'suspicious-userlogout' => 'લોગ આઉટ કરવાની તમારી વિનંતિ પૂરી ન કરી શકાઇ. એમ લાગે છે કે તેને તૃટિ પામેલ બ્રાઉઝર કે પ્રોક્સી દ્વારા મોકલાઈ હતી.',
 'createacct-another-realname-tip' => 'સાચું નામ મરજીયાત છે.
 જો તમે તે આપવાનું પસંદ કરશો, તો તેનો ઉપયોગ તમે કરેલ યોગદાનનું શ્રેય આપવા માટે થશે.',
+'pt-login' => 'પ્રવેશ કરો',
+'pt-createaccount' => 'ખાતું બનાવો',
+'pt-userlogout' => 'બહાર નીકળો',
 
 # Email sending
 'php-mail-error-unknown' => 'PHPની મેલ() કામગીરીમાં અજ્ઞાત ત્રુટિ',
@@ -710,8 +713,7 @@ $2',
 
 # Change password dialog
 'changepassword' => 'ગુપ્તસંજ્ઞા બદલો',
-'resetpass_announce' => 'તમે હંગામી ઇમેઇલ કોડ સાથે લોગ ઇન કર્યું.
-લોગીંગ પુરૂં કરવા માટે તમારે નવી ગુપ્ત સંજ્ઞા (પાસવર્ડ) આપવો પડશે:',
+'resetpass_announce' => 'પ્રવેશ પૂર્ણ કરવા માટે, તમારે નવો પાસવર્ડ ગોઠવવો જ પડશે.',
 'resetpass_text' => '<!-- અહીં ટેક્સટ ઉમેરો -->',
 'resetpass_header' => 'ખાતાની ગુપ્તસંજ્ઞા બદલો',
 'oldpassword' => 'જુની ગુપ્તસંજ્ઞા:',
@@ -1208,7 +1210,7 @@ $1",
 'shown-title' => 'પ્રતિ પાને $1 {{PLURAL:$1|પરિણામ|પરિણામો}} બતાવો',
 'viewprevnext' => 'જુઓ: ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "''' આ વિકિ પર  \"[[:\$1]]\" નામે પાનું પહેલેથી અસ્તિત્વમાં છે.'''",
-'searchmenu-new' => "'''આ વિકિ પર \"[[:\$1]]\" નામે પાનું બનાવો!'''",
+'searchmenu-new' => '<strong>આ વિકિ પર "[[:$1]]" પાનું બનાવો!</strong> {{PLURAL:$2|0=|તમારી શોધમાં મળેલ પાનું પણ જુઓ.|તમારી શોધમાં મળેલ પરિણામો પણ જુઓ.}}',
 'searchprofile-articles' => 'લેખનું પાનું',
 'searchprofile-project' => 'મદદ અને યોજના પાનું',
 'searchprofile-images' => 'દ્રશ્ય શ્રાવ્ય માધ્યમ',
@@ -1219,7 +1221,7 @@ $1",
 'searchprofile-images-tooltip' => 'ફાઇલ શોધો',
 'searchprofile-everything-tooltip' => 'બધે જ શોધો (ચર્ચાનાં પાના સહિત)',
 'searchprofile-advanced-tooltip' => 'સ્થાનીય નામસ્થળોમાં શોધો:',
-'search-result-size' => '$1 ({{PLURAL:$2|1 શબ્દ|$2 શબ્દો}})',
+'search-result-size' => '$1 ({{PLURAL:$2| શબ્દ|$2 શબ્દો}})',
 'search-result-category-size' => '{{PLURAL:$1|1 સભ્ય|$1 સભ્યો}} ({{PLURAL:$2|1 ઉપ શ્રેણી|$2 ઉપ શ્રેણીઓ}}, {{PLURAL:$3|1 ફાઇલ|$3 ફાઇલો}})',
 'search-result-score' => 'પ્રસ્તુતિ: $1%',
 'search-redirect' => '(અન્યત્ર પ્રસ્થાન $1)',
@@ -1543,14 +1545,26 @@ HTML નાકું ચકાસો',
 'recentchanges-label-unpatrolled' => 'આ ફેરફાર હજી ચકાસાયો નથી',
 'recentchanges-label-plusminus' => 'પાનાનું કદ આપેલા અંકો જેટલાં બાઈટ્સ જેટલું બદલ્યુ છે.',
 'recentchanges-legend-newpage' => '([[Special:NewPages|નવા પાનાઓની યાદી]] પણ જુઓ)',
-'rcnotefrom' => "નીચે '''$2'''થી થયેલાં '''$1''' ફેરફારો દર્શાવ્યાં છે.",
+'rcnotefrom' => 'નીચે <strong>$2</strong> થી ફેરફારો દર્શાવેલ છે (<strong>$1</strong> સુધી દર્શાવલે છે).',
 'rclistfrom' => '$1 બાદ થયેલા નવા ફેરફારો બતાવો',
 'rcshowhideminor' => 'નાના ફેરફારો $1',
+'rcshowhideminor-show' => 'બતાવો',
+'rcshowhideminor-hide' => 'છુપાવો',
 'rcshowhidebots' => 'બૉટો $1',
-'rcshowhideliu' => 'લૉગ ઇન થયેલાં સભ્યો $1',
+'rcshowhidebots-show' => 'બતાવો',
+'rcshowhidebots-hide' => 'છુપાવો',
+'rcshowhideliu' => '$1 નોંધણી કરેલ સભ્યો',
+'rcshowhideliu-show' => 'બતાવો',
+'rcshowhideliu-hide' => 'છુપાવો',
 'rcshowhideanons' => 'અનામી સભ્યો $1',
+'rcshowhideanons-show' => 'બતાવો',
+'rcshowhideanons-hide' => 'છુપાવો',
 'rcshowhidepatr' => '$1 ચોકીયાત ફેરફારો',
+'rcshowhidepatr-show' => 'બતાવો',
+'rcshowhidepatr-hide' => 'છુપાવો',
 'rcshowhidemine' => 'મારા ફેરફારો $1',
+'rcshowhidemine-show' => 'બતાવો',
+'rcshowhidemine-hide' => 'છુપાવો',
 'rclinks' => 'છેલ્લાં $2 દિવસમાં થયેલા છેલ્લાં $1 ફેરફારો દર્શાવો<br />$3',
 'diff' => 'ભેદ',
 'hist' => 'ઇતિહાસ',
@@ -2026,6 +2040,10 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization. જુઓ',
 'protectedpages-indef' => 'ફક્ત અનિશ્ચિત સુરક્ષા ધરાવતા પાના',
 'protectedpages-cascade' => 'માત્ર પગથિયામય સુરક્ષા વાળા પગ',
 'protectedpagesempty' => 'આ વિકલ્પો દ્વારા કોઈ પાના સુરક્ષિત કરાયા નથી.',
+'protectedpages-page' => 'પાનું',
+'protectedpages-reason' => 'કારણ',
+'protectedpages-unknown-timestamp' => 'અજ્ઞાત',
+'protectedpages-unknown-performer' => 'અજ્ઞાત સભ્ય',
 'protectedtitles' => 'સંરક્ષિત શીર્ષકો',
 'protectedtitlesempty' => 'આ પરિબળો દ્વારા કોઇ પણ શીર્ષકો સચવાયા નથી.',
 'listusers' => 'સભ્યોની યાદી',
@@ -2585,8 +2603,9 @@ $1',
 'change-blocklink' => 'પ્રતિબંધમાં ફેરફાર કરો',
 'contribslink' => 'યોગદાન',
 'emaillink' => 'ઈ-મેલ મોકલો',
-'autoblocker' => 'તમારા પર સ્વયંચાલિત રીતે રોક લગાવાઇ છે કેમકે તમારો IP હાલમાં "[[User:$1|$1]]" સભ્ય દ્વારા વપરાયો છે.
-તેનું કારણ આ છે : "$2"',
+'autoblocker' => 'તમારા પર સ્વયંચાલિત રીતે રોક લગાવાઇ છે કેમ કે તમારું IP સરનામું હાલમાં "[[User:$1|$1]]" સભ્ય દ્વારા વપરાયેલ છે.
+
+$1નાં પ્રતિબંધનું કારણ "$2" છે',
 'blocklogpage' => 'પ્રતિબંધ સૂચિ',
 'blocklog-showlog' => 'આ સભ્ય પર પહેલા રોક લગાવાઈ છે.
 રોકા લગાવાયેલા સભ્યોની યાદિ આ મુજબ છે',
@@ -2608,7 +2627,7 @@ $1',
 'range_block_disabled' => 'પ્રબંધકના સમૂહીક રોક લગાડવાનો અધિકાર નીષ્ક્રિય',
 'ipb_expiry_invalid' => 'સમાપ્તિનો સમય માન્ય નથી.',
 'ipb_expiry_temp' => 'સંતાડેલા સભ્યનામ પ્રતિબંધનો કાયમી જ હોવા જોઇએ.',
-'ipb_hide_invalid' => 'àª\86 àªªàª¾àª¨àª¾àª¨à«\87 àª\9bà«\81પાવવà«\8b àª¸àª\82ભવ àª¨àª¥à«\80 àª¤à«\87માàª\82 àª\98ણા àª¬àª§àª¾àª\82 àª«à«\87રફારà«\8b àª\9bà«\87',
+'ipb_hide_invalid' => 'àª\86 àª\96ાતાàª\82નà«\87 àª\9bà«\81પાવવાàª\82 àª\85સàª\95à«\8dષમ; àª¤à«\87માàª\82 {{PLURAL:$1|àª\8fàª\95 àª«à«\87રફાર|$1 àª«à«\87રફારà«\8b}} àª\9bà«\87.',
 'ipb_already_blocked' => ' "$1" પહેલેથી પ્રતિબંધિત છે',
 'ipb-needreblock' => '$1 પહેલેથી પ્રતિબંધિત છે.
 તમારે આ સેટીંગ બદલવી છે?',
@@ -2781,6 +2800,7 @@ $1',
 'allmessages-prefix' => 'ઉપસર્ગ દ્વારા અલગ તારવો',
 'allmessages-language' => 'ભાષા:',
 'allmessages-filter-submit' => 'કરો',
+'allmessages-filter-translate' => 'ભાષાંતર કરો',
 
 # Thumbnails
 'thumbnail-more' => 'વિસ્તૃત કરો',
@@ -2872,7 +2892,7 @@ $2',
 'tooltip-pt-preferences' => 'તમારી પસંદગીઓ',
 'tooltip-pt-watchlist' => 'તમે દેખરેખ રાખી રહ્યાં હોવ તેવા પાનાઓની યાદી',
 'tooltip-pt-mycontris' => 'તમારા યોગદાનની યાદી',
-'tooltip-pt-login' => 'àª\86પનà«\87 àª²à«\8bàª\97 àª\87ન કરવા ભલામણ કરવામાં આવે છે, જોકે તે આવશ્યક નથી',
+'tooltip-pt-login' => 'àª\86પનà«\87 àªªà«\8dરવà«\87શ કરવા ભલામણ કરવામાં આવે છે, જોકે તે આવશ્યક નથી',
 'tooltip-pt-logout' => 'બહાર નીકળો/લૉગ આઉટ કરો',
 'tooltip-ca-talk' => 'અનુક્રમણિકાનાં પાના વિષે ચર્ચા',
 'tooltip-ca-edit' => "આપ આ પાનામાં ફેરફાર કરી શકો છો, કાર્ય સુરક્ષિત કરતાં પહેલાં 'ઝલક' બટન ઉપર ક્લિક કરીને જોઇ લેશો",
@@ -2888,8 +2908,8 @@ $2',
 'tooltip-ca-unwatch' => 'આ પાનું તમારી ધ્યાનસૂચીમાંથી કાઢી નાખો',
 'tooltip-search' => '{{SITENAME}} શોધો',
 'tooltip-search-go' => 'આ ચોક્કસ જોડણી વાળુ પાનુ જો અસ્તિત્વમાં હોય તો તેના પર જાવ',
-'tooltip-search-fulltext' => 'àª\86 àª²àª\96ાણ àªµàª¾àª³àª¾ પાનાઓ શોધો',
-'tooltip-p-logo' => 'મુખપૃષ્ઠ',
+'tooltip-search-fulltext' => 'àª\86 àª²àª\96ાણ àª§àª°àª¾àªµàª¤àª¾àª\82 પાનાઓ શોધો',
+'tooltip-p-logo' => 'મુખપૃષ્ઠની મુલાકાત લો',
 'tooltip-n-mainpage' => 'મુખપૃષ્ઠ પર જાઓ',
 'tooltip-n-mainpage-description' => 'મુખ્ય પાના પર જાઓ',
 'tooltip-n-portal' => 'પરિયોજના વિષે, આપ શું કરી શકો અને વસ્તુઓ ક્યાં શોધશો',
@@ -2904,7 +2924,7 @@ $2',
 'tooltip-t-contributions' => 'આ સભ્યનાં યોગદાનોની યાદી જુઓ',
 'tooltip-t-emailuser' => 'આ સભ્યને ઇ-મેલ મોકલો',
 'tooltip-t-upload' => 'ફાઇલ ચડાવો',
-'tooltip-t-specialpages' => 'બધા àª\96ાસ àªªàª¾àª¨àª¾àª\93નà«\80 àª¸à«\82àª\9aિ',
+'tooltip-t-specialpages' => 'બધા àª\96ાસ àªªàª¾àª¨àª¾àª\82àª\93નà«\80 àª¯àª¾àª¦à«\80',
 'tooltip-t-print' => 'આ પાનાની છાપવા માટેની આવૃત્તિ',
 'tooltip-t-permalink' => 'પાનાનાં આ પુનરાવર્તનની સ્થાયી કડી',
 'tooltip-ca-nstab-main' => 'સૂચિ વાળું પાનુ જુઓ',
@@ -3599,6 +3619,10 @@ $5
 'imgmultigo' => 'જાઓ!',
 'imgmultigoto' => 'પાના  $1 પર જાવ',
 
+# Language selector for translatable SVGs
+'img-lang-default' => '(મૂળભુત ભાષા)',
+'img-lang-go' => 'જાઓ',
+
 # Table pager
 'ascending_abbrev' => 'ચડતો ક્ર્મ',
 'descending_abbrev' => 'ઉતરતો ક્ર્મ',
@@ -3679,7 +3703,14 @@ $5
 'version-hook-name' => 'ખૂંટાનું નામ્',
 'version-hook-subscribedby' => 'દ્વ્રારા લાભાન્વીત',
 'version-version' => '(આવૃત્તિ $1)',
-'version-license' => 'પરવાનો',
+'version-license' => 'મીડિઆવિકિ લાયસન્સ',
+'version-ext-license' => 'લાયસન્સ',
+'version-ext-colheader-version' => 'આવૃત્તિ',
+'version-ext-colheader-license' => 'લાયસન્સ',
+'version-ext-colheader-description' => 'વર્ણન',
+'version-ext-colheader-credits' => 'લેખકો',
+'version-license-title' => '$1 માટે લાયસન્સ',
+'version-credits-title' => '$1 માટે યશ',
 'version-poweredby-credits' => "આ વિકિ  '''[https://www.mediawiki.org/ MediaWiki]''' દ્વારા ચાલે છે, પ્રકાશનાધિકાર © 2001-$1 $2.",
 'version-poweredby-others' => 'અન્યો',
 'version-poweredby-translators' => 'ટ્રાન્સલેટવિકિ.નેટ ભાષાંતરકર્તાઓ',
@@ -3716,7 +3747,7 @@ $5
 'fileduplicatesearch-noresults' => ' "$1" નામ ધરાવતી કોઇ ફાઇલ ન મળી',
 
 # Special:SpecialPages
-'specialpages' => 'ખાસ પાનાં',
+'specialpages' => 'ખાસ પાનાં',
 'specialpages-note' => '* નિયમિત ખાસ પાનાં.
 * <span class="mw-specialpagerestricted">પ્રતિબંધિત ખાસ પાનાં.</span>',
 'specialpages-group-maintenance' => 'સમારકામ અહેવાલ',
index 43a760e..16ba1ce 100644 (file)
@@ -950,7 +950,7 @@ $2',
 'resetpass-temp-password' => 'סיסמה זמנית:',
 'resetpass-abort-generic' => 'שינוי הסיסמה בוטל על־ידי הרחבה.',
 'resetpass-expired' => 'סיסמתכם פקעה. אנא הגדירו סיסמה חדשה כדי להיכנס.',
-'resetpass-expired-soft' => 'סיסמתכם פקעה, ויש לאפס אותה. אנא בחרו סיסמה חדשה כעת, או לחצו על "ביטול" כדי לאפס אותה מאוחר יותר.',
+'resetpass-expired-soft' => 'סיסמתכם פקעה ויש לאפס אותה. אנא בחרו סיסמה חדשה כעת, או לחצו על "{{int:resetpass-submit-cancel}}" כדי לאפס אותה מאוחר יותר.',
 
 # Special:PasswordReset
 'passwordreset' => 'איפוס סיסמה',
@@ -1811,8 +1811,8 @@ $1",
 'recentchanges-legend-heading' => "'''מקרא:'''",
 'recentchanges-legend-newpage' => '(ראו גם [[Special:NewPages|רשימת דפים חדשים]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => 'להלן <b>$1</b> השינויים האחרונים שבוצעו החל מתאריך <b>$2</b>:',
-'rclistfrom' => 'הצגת שינויים חדשים החל מ־$1',
+'rcnotefrom' => 'להלן השינויים שבוצעו החל מ‏‏֫־<b>$2</b> (עד <b>$1</b> מוצגים).',
+'rclistfrom' => 'הצגת שינויים חדשים החל מ־$2, $3',
 'rcshowhideminor' => '$1 שינויים משניים',
 'rcshowhideminor-show' => 'הצגת',
 'rcshowhideminor-hide' => 'הסתרת',
@@ -2794,6 +2794,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'כתובת IP זו חסומה כרגע.
 הפעולה האחרונה ביומן החסימות מוצגת להלן:',
 'sp-contributions-search' => 'חיפוש תרומות',
+'sp-contributions-suppresslog' => 'תרומות משתמש מוסתרות',
 'sp-contributions-username' => 'שם משתמש או כתובת IP:',
 'sp-contributions-toponly' => 'הצגת עריכות שהן הגרסאות האחרונות בלבד',
 'sp-contributions-newonly' => 'הצגת עריכות שהן יצירות של דפים בלבד',
index eb498f7..6bfdabb 100644 (file)
@@ -500,7 +500,7 @@ $messages = array(
 'searcharticle' => 'Kreni',
 'history' => 'Stare izmjene',
 'history_short' => 'Stare izmjene',
-'updatedmarker' => 'obnovljeno od zadnjeg posjeta',
+'updatedmarker' => 'obnovljeno od posljednjeg posjeta',
 'printableversion' => 'Inačica za ispis',
 'permalink' => 'Trajna poveznica',
 'print' => 'Ispiši',
@@ -540,7 +540,7 @@ $messages = array(
 'otherlanguages' => 'Drugi jezici',
 'redirectedfrom' => '(Preusmjereno s $1)',
 'redirectpagesub' => 'Preusmjeravanje',
-'lastmodifiedat' => 'Datum zadnje promjene na ovoj stranici: $2, $1',
+'lastmodifiedat' => 'Vrijeme i datum posljednje promjene na ovoj stranici: $2, $1',
 'viewcount' => 'Ova stranica je pogledana {{PLURAL:$1|$1 put|$1 puta}}.',
 'protectedpage' => 'Zaštićena stranica',
 'jumpto' => 'Skoči na:',
@@ -587,7 +587,7 @@ $1',
 'youhavenewmessagesfromusers' => 'Imate $1 {{PLURAL:$3||od $3 suradnika|od $3 suradnika}} ($2).',
 'youhavenewmessagesmanyusers' => 'Imate $1 od više suradnika ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|novu poruku|$1 nove poruke|$1 novih poruka}}',
-'newmessagesdifflinkplural' => '{{PLURAL:$1|zadnje uređivanje|zadnja $1 uređivanja|zadnjih $1 uređivanja}} na stranici za razgovor',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|posljednje uređivanje|posljednja $1 uređivanja|posljednjih $1 uređivanja}} na stranici za razgovor',
 'youhavenewmessagesmulti' => 'Imate nove poruke na $1',
 'editsection' => 'uredi',
 'editold' => 'uredi',
@@ -675,7 +675,9 @@ Nema obrazloženja ili poruke o pogrješci.',
 'badtitle' => 'Loš naslov',
 'badtitletext' => 'Navedeni naslov stranice nepravilan ili loše formirana interwiki poveznica.',
 'perfcached' => 'Sljedeći podaci su iz međuspremnika i možda nisu najsvježiji. Međuspremnik sadrži $1 {{PLURAL:$1|rezultat|rezultata}} pretraživanja.',
-'perfcachedts' => 'Sljedeći podaci su iz međuspremnika i zadnji puta su ažurirani u $1. Međuspremnik sadrži $4 {{PLURAL:$4|rezultat|rezultata}} pretraživanja.',
+'perfcachedts' => 'Sljedeći podaci su iz međuspremnika i posljednji puta su ažurirani u $1. Međuspremnik sadrži $4 {{PLURAL:$4|rezultat|rezultata}} pretraživanja.
+
+Više o ovoj [[Wikipedija:Posebne stranice|posebnoj stranici]] na [[Razgovor Wikipedija:Special:{{PAGENAME}}]].',
 'querypage-no-updates' => 'Osvježavanje ove stranice je trenutačno onemogućeno. Nove promjene neće biti vidljive.',
 'viewsource' => 'Vidi izvornik',
 'viewsource-title' => 'Vidi kôd stranice $1',
@@ -815,7 +817,7 @@ koristiti staru lozinku.',
 'blocked-mailpassword' => 'Vašoj IP adresi je blokirano uređivanje stranica, a da bi se spriječila nedopuštena radnja, mogućnost zahtijevanja nove lozinke je također onemogućena.',
 'eauthentsent' => 'Na navedenu adresu poslana je e-poruka s potvrdom.
 Prije nego što pošaljemo daljnje poruke, molimo Vas otvorite e-poruku i slijedite u njemu sadržana uputstva kako biste potvrdili da je adresa e-pošte zaista Vaša.',
-'throttled-mailpassword' => 'Već Vam je poslan e-mail za promjenu zaporke, u {{PLURAL:$1|zadnjih sat vremena|zadnja $1 sata|zadnjih $1 sati}}.
+'throttled-mailpassword' => 'Već Vam je poslan e-mail za promjenu zaporke, u {{PLURAL:$1|posljednjih sat vremena|posljednja $1 sata|posljednjih $1 sati}}.
 Da bi spriječili zloupotrebu, moguće je poslati samo jedan e-mail za promjenu zaporke {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.',
 'mailerror' => 'Pogrješka pri slanju e-pošte: $1',
 'acct_creation_throttle_hit' => 'Posjetitelji ovog wikija koji rabe Vašu IP adresu napravili su {{PLURAL:$1|1 račun|$1 računa}} u posljednjem danu, što je najveći dopušteni broj u tom vremenskom razdoblju.
@@ -843,6 +845,9 @@ Molimo Vas pričekajte $1 prije nego što pokušate ponovno.',
 'suspicious-userlogout' => 'Vaš zahtjev za odjavu je odbijen jer to izgleda kao da je poslan preko pokvarenog preglednika ili keširanog posrednika (proxyja).',
 'createacct-another-realname-tip' => 'Pravo ime nije obvezno. 
 Ako ga navedete, bit će korišteno za pripisivanje Vaših doprinosa.',
+'pt-login' => 'Prijavi se',
+'pt-createaccount' => 'Otvori novi suradnički račun',
+'pt-userlogout' => 'odjavi se',
 
 # Email sending
 'php-mail-error-unknown' => 'Nepoznata pogrješka u funkciji PHP-poruke()',
@@ -1144,7 +1149,7 @@ Neki predlošci neće biti uključeni.',
 'converter-manual-rule-error' => 'Pronađena je pogrješka u pravilu ručnog prijevoda',
 
 # "Undo" feature
-'undo-success' => 'Izmjena je uklonjena (tekst u okviru ispod ne sadrži zadnju izmjenu). Molim sačuvajte stranicu (provjerite sažetak).',
+'undo-success' => 'Izmjena je uklonjena (tekst u okviru ispod ne sadrži posljednju izmjenu). Molim sačuvajte stranicu (provjerite sažetak).',
 'undo-failure' => 'Ova izmjena ne može biti uklonjena zbog postojanja međuinačica.',
 'undo-norev' => 'Izmjena nije mogla biti uklonjena jer ne postoji ili je obrisana.',
 'undo-summary' => 'Uklanjanje izmjene $1 što ju je unio/unijela [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]])',
@@ -1588,7 +1593,7 @@ Ne smije biti duži od $1 {{PLURAL:$1|znaka|znaka|znakova}}.',
 'right-viewmyprivateinfo' => 'Vidite svoje privatne podatke (npr. adresu e-pošte, stvarno ime)',
 'right-editmyprivateinfo' => 'Uredite svoje privatne podatke (npr. adresa e-pošte, stvarno ime)',
 'right-editmyoptions' => 'Uredite svoje postavke',
-'right-rollback' => 'Brzo uklanjanje izmjena zadnjeg suradnika na određenoj stranici',
+'right-rollback' => 'Brzo uklanjanje izmjena posljednjeg suradnika na određenoj stranici',
 'right-markbotedits' => 'Označavanje uklonjenih izmjena kao izmjenu bota',
 'right-noratelimit' => 'Bez vremenskog ograničenja uređivanja',
 'right-import' => 'Uvoženje stranica s drugih wikija',
@@ -1672,12 +1677,24 @@ Ne smije biti duži od $1 {{PLURAL:$1|znaka|znaka|znakova}}.',
 'rcnotefrom' => 'Slijede promjene od <b>$2</b> (prikazano ih je do <b>$1</b>).',
 'rclistfrom' => 'Prikaži nove promjene počevši od $1',
 'rcshowhideminor' => '$1 manje promjene',
+'rcshowhideminor-show' => 'prikaži',
+'rcshowhideminor-hide' => 'sakrij',
 'rcshowhidebots' => '$1 botove',
+'rcshowhidebots-show' => 'prikaži',
+'rcshowhidebots-hide' => 'sakrij',
 'rcshowhideliu' => '$1 prijavljene suradnike',
+'rcshowhideliu-show' => 'prikaži',
+'rcshowhideliu-hide' => 'sakrij',
 'rcshowhideanons' => '$1 neprijavljene suradnike',
+'rcshowhideanons-show' => 'prikaži',
+'rcshowhideanons-hide' => 'sakrij',
 'rcshowhidepatr' => '$1 provjerene promjene',
+'rcshowhidepatr-show' => 'prikaži',
+'rcshowhidepatr-hide' => 'sakrij',
 'rcshowhidemine' => '$1 moje promjene',
-'rclinks' => 'Prikaži zadnjih $1 promjena u zadnjih $2 dana; $3',
+'rcshowhidemine-show' => 'prikaži',
+'rcshowhidemine-hide' => 'sakrij',
+'rclinks' => 'Prikaži posljednjih $1 promjena {{PLURAL:$2|prethodni dan|u posljednja $2 dana|u posljednjih $2 dana}}<br />$3',
 'diff' => 'razl',
 'hist' => 'pov',
 'hide' => 'sakrij',
@@ -2233,7 +2250,7 @@ Podržani {{PLURAL:$2|protokol|protokoli}}: <code>$1</code> (default je http://
 
 # Special:ActiveUsers
 'activeusers' => 'Popis aktivnih suradnika',
-'activeusers-intro' => 'Ovo je popis suradnika koji su napravili neku aktivnost u {{PLURAL:$1|zadnji $1 dan|zadnja $1 dana|zadnjih $1 dana}}.',
+'activeusers-intro' => 'Ovo je popis suradnika koji su napravili neku aktivnost u {{PLURAL:$1|posljednji $1 dan|posljednja $1 dana|posljednjih $1 dana}}.',
 'activeusers-count' => '{{PLURAL:$1|nedavna $1 izmjena|nedavne $1 izmjene|nedavnih $1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}',
 'activeusers-from' => 'Prikaži suradnike počevši od:',
 'activeusers-hidebots' => 'Sakrij botove',
@@ -2320,12 +2337,12 @@ Promjene na toj stranici i njenoj stranici za razgovor bit će prikazane na popi
 'notvisiblerev' => 'Izmjena je obrisana',
 'watchlist-details' => '{{PLURAL:$1|$1 stranica|$1 stranice|$1 stranica}} se nalazi na popisu praćenja, ne brojeći stranice za razgovor.',
 'wlheader-enotif' => 'Uključeno je izvješćivanje e-poštom.',
-'wlheader-showupdated' => "Stranice koje su promijenjene od Vašeg zadnjeg posjeta prikazane su '''podebljano'''",
+'wlheader-showupdated' => "Stranice koje su promijenjene od Vašeg posljednjeg posjeta prikazane su '''podebljano'''",
 'watchmethod-recent' => 'provjera nedavnih promjena praćenih stranica',
 'watchmethod-list' => 'provjera praćanih stranica za nedavne promjene',
 'watchlistcontains' => 'Vaš popis praćenja sadrži $1 {{PLURAL:$1|stranicu|stranice|stranica}}.',
 'iteminvalidname' => "Problem s izborom '$1', ime nije valjano...",
-'wlshowlast' => 'Prikaži zadnjih $1 sati $2 dana $3',
+'wlshowlast' => 'Prikaži posljednjih $1 sati $2 dana $3',
 'watchlist-options' => 'Izbornik popisa praćenja',
 
 # Displayed when you click the "watch" button and it is in the process of watching
@@ -2355,11 +2372,11 @@ $PAGEINTRO $NEWPAGE
 
 Sažetak urednika: $PAGESUMMARY $PAGEMINOREDIT
 
-Možete kontaktirati suradnika koji je zadnji uređivao stranicu:
+Možete kontaktirati suradnika koji je posljednji uređivao stranicu:
 mail: $PAGEEDITOR_EMAIL
 wiki: $PAGEEDITOR_WIKI
 
-Do Vašeg ponovnog posjeta stranici nećete dobivati nove obavijesti. Postavke za izvješćivanje možete resetirati za sve praćene stranice svog popisa praćenja.
+Do Vašeg ponovnog posjeta stranici nećete dobivati nove obavijesti. Postavke za izvješćivanje možete vratiti na prvotno zadane za sve praćene stranice svog popisa praćenja.
 
 Vaš sustav izvješćivanja {{SITENAME}}.
 
@@ -2423,10 +2440,10 @@ Sva vremena su prema poslužiteljevom vremenu.',
 
 Posljednju promjenu napravio je [[User:$3|$3]] ([[User talk:$3|Razgovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
 'editcomment' => "Sažetak promjene je bio: \"''\$1''\".",
-'revertpage' => 'Uklonjena promjena suradnika $2, vraćeno na zadnju inačicu suradnika $1',
+'revertpage' => 'Uklonjena promjena suradnika $2, vraćeno na posljednju inačicu suradnika $1',
 'revertpage-nouser' => 'Vraćene izmjene suradnika (suradničko ime uklonjeno) na posljednju inačicu suradnika [[User:$1|$1]]',
 'rollback-success' => 'Uklonjeno uređivanje {{GENDER:$1|suradnika|suradnice}} $1
-vraćeno na zadnju inačicu {{GENDER:$2|suradnika|suradnice}} $2.',
+vraćeno na posljednju inačicu {{GENDER:$2|suradnika|suradnice}} $2.',
 
 # Edit tokens
 'sessionfailure-title' => 'Prekid sesije',
@@ -2511,7 +2528,7 @@ Baza se povremeno čisti od ovakvih stranica.',
 Ako želite vratiti određene izmjene, označite ih i kliknite '''''{{int:undeletebtn}}'''''.",
 'undeleterevisions' => '$1 {{PLURAL:$1|inačica je arhivirana|inačice su arhivirane|inačica je arhivirano}}',
 'undeletehistory' => 'Ako vratite izbrisanu stranicu, bit će vraćene i sve prijašnje promjene. Ako je u međuvremenu stvorena nova stranica s istim imenom, vraćena stranica bit će upisana kao prijašnja promjena sadašnje.',
-'undeleterevdel' => 'Vraćanje stranice neće biti izvršeno ako je rezultat toga djelomično brisanje zadnjeg uređivanja.
+'undeleterevdel' => 'Vraćanje stranice neće biti izvršeno ako je rezultat toga djelomično brisanje posljednjeg uređivanja.
 U takvim slučajevima morate isključiti ili otkriti najnovije obrisane promjene.',
 'undeletehistorynoadmin' => 'Ovaj je članak izbrisan. Razlog za brisanje prikazan je u donjem sažetku, zajedno s
 detaljima o suradnicima koji su uređivali ovu stranicu prije brisanja.
@@ -3018,7 +3035,7 @@ Snimite je na svoje računalo i postavite je ovdje.',
 'tooltip-watchlistedit-raw-submit' => 'Osvježi popis praćenja',
 'tooltip-recreate' => 'Vrati stranicu unatoč tome što je obrisana',
 'tooltip-upload' => "Pokreni snimanje (''upload'')",
-'tooltip-rollback' => '"Ukloni" uklanja uređivanja zadnjeg suradnika na ovoj stranici.',
+'tooltip-rollback' => '"Ukloni" uklanja uređivanja posljednjeg suradnika na ovoj stranici.',
 'tooltip-undo' => '"Ukloni ovu izmjenu" uklanja ovu izmjenu i otvara okvir za uređivanje. Omogućava unošenje razloga u sažetak.',
 'tooltip-preferences-save' => 'Spremi postavke',
 'tooltip-summary' => 'Unesite kratki sažetak',
@@ -3038,7 +3055,7 @@ Snimite je na svoje računalo i postavite je ovdje.',
 'anonymous' => 'Neprijavljeni {{PLURAL:$1|suradnik|suradnici}} projekta {{SITENAME}}',
 'siteuser' => 'Suradnik $1 na projektu {{SITENAME}}',
 'anonuser' => '{{SITENAME}} anonimni suradnik $1',
-'lastmodifiedatby' => 'Ovu je stranicu zadnji put mijenjao dana $2, $1 suradnik $3.',
+'lastmodifiedatby' => 'Ovu je stranicu posljednji put {{GENDER:$4|mijenjao suradnik|mijenjala suradnica}} $3 dana $1 u $2.',
 'othercontribs' => 'Temelji se na doprinosu suradnika $1.',
 'others' => 'drugih',
 'siteusers' => '{{SITENAME}} {{PLURAL:$2|suradnik|suradnici}} $1',
@@ -3052,7 +3069,7 @@ Snimite je na svoje računalo i postavite je ovdje.',
 Razlog je vjerojatno vanjska poveznica koja se nalazi na crnom popisu.',
 'spamprotectionmatch' => 'Naš filtar spama reagirao je na sljedeći tekst: $1',
 'spambot_username' => 'MediaWiki zaštita od spama',
-'spam_reverting' => 'Vraćam na zadnju inačicu koja ne sadrži poveznice na $1',
+'spam_reverting' => 'Vraćam na posljednju inačicu koja ne sadrži poveznice na $1',
 'spam_blanking' => 'Sve inačice sadrže poveznice na $1, brišem cjelokupni sadržaj',
 'spam_deleting' => 'Sve inačice sadržale su poveznice na $1, brišem cjelokupni sadržaj',
 'simpleantispam-label' => "Anti-spam provjera.
@@ -3081,10 +3098,10 @@ Razlog je vjerojatno vanjska poveznica koja se nalazi na crnom popisu.',
 'pageinfo-firstuser' => 'Suradnik koji je stvorio stranicu',
 'pageinfo-firsttime' => 'Datum stvaranja stranice',
 'pageinfo-lastuser' => 'Posljednji urednik stranice',
-'pageinfo-lasttime' => 'Datum zadnjeg uređivanja',
+'pageinfo-lasttime' => 'Datum posljednjeg uređivanja',
 'pageinfo-edits' => 'Ukupan broj uređivanja',
 'pageinfo-authors' => 'Broj različitih autora',
-'pageinfo-recent-edits' => 'Broj uređivanja (u zadnjih $1)',
+'pageinfo-recent-edits' => 'Broj uređivanja (u posljednjih $1)',
 'pageinfo-recent-authors' => 'Broj različitih autora u gornjem razdoblju',
 'pageinfo-magic-words' => '{{PLURAL:$1|Magična riječ - varijabla|Magične riječi - varijable}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Postoji|Postoje|Postoji}} $1 {{PLURAL:$1|skrivena kategorija|skrivene kategorije|skrivenih kategorija}}',
@@ -3167,7 +3184,7 @@ Njegovim izvršavanjem mogli biste oštetiti svoj sustav.",
 # Special:NewFiles
 'newimages' => 'Galerija novih datoteka',
 'imagelisttext' => 'Ispod je popis {{PLURAL:$1|$1 slike|$1 slike|$1 slika}} složen $2.',
-'newimages-summary' => 'Ova posebna stranica pokazuje zadnje nedavno postavljene datoteke.',
+'newimages-summary' => 'Ova posebna stranica pokazuje posljednje nedavno postavljene datoteke.',
 'newimages-legend' => 'Filtar',
 'newimages-label' => 'Naziv datoteke (ili njen dio):',
 'showhidebots' => '($1 botova)',
@@ -3244,7 +3261,7 @@ Svaka sljedeća poveznica u istom retku je izuzetak, npr. kod stranica gdje se s
 'exif-primarychromaticities' => 'Kromaticitet primarnih boja',
 'exif-ycbcrcoefficients' => 'Matrični koeficijenti preobrazbe kolor prostora',
 'exif-referenceblackwhite' => 'Mjesto bijele i crne točke',
-'exif-datetime' => 'Datum zadnje promjene datoteke',
+'exif-datetime' => 'Datum posljednje promjene datoteke',
 'exif-imagedescription' => 'Ime slike',
 'exif-make' => 'Proizvođač kamere',
 'exif-model' => 'Model kamere',
@@ -3374,7 +3391,7 @@ Svaka sljedeća poveznica u istom retku je izuzetak, npr. kod stranica gdje se s
 'exif-serialnumber' => 'Serijski broj kamere',
 'exif-cameraownername' => 'Vlasnik kamere',
 'exif-label' => 'Oznaka',
-'exif-datetimemetadata' => 'Datum zadnje promjene metapodataka',
+'exif-datetimemetadata' => 'Datum posljednje promjene metapodataka',
 'exif-nickname' => 'Neformalni naziv slike',
 'exif-rating' => 'Ocjena (od 5)',
 'exif-rightscertificate' => 'Certifikat za upravljanje pravima',
@@ -3736,8 +3753,8 @@ Potvrdite namjeru vraćanja ovog članka.",
 'livepreview-error' => 'Spajanje nije uspjelo: $1 "$2". Pokušajte normalni pretpregled.',
 
 # Friendlier slave lag warnings
-'lag-warn-normal' => 'Moguće je da izmjene nastale zadnjih $1 {{PLURAL:$1|sekundu|sekundi}} neće biti vidljive na ovom popisu.',
-'lag-warn-high' => 'Zbog kašnjenja baze podataka, moguće je da promjene napravljene u zadnjih $1 {{PLURAL:$1|sekundu|sekunde|sekundi}} nisu prikazane u popisu.',
+'lag-warn-normal' => 'Moguće je da izmjene nastale posljednjih $1 {{PLURAL:$1|sekundu|sekundi}} neće biti vidljive na ovom popisu.',
+'lag-warn-high' => 'Zbog kašnjenja baze podataka, moguće je da promjene napravljene u posljednjih $1 {{PLURAL:$1|sekundu|sekunde|sekundi}} nisu prikazane u popisu.',
 
 # Watchlist editor
 'watchlistedit-numitems' => 'Vaš popis praćenja sadrži {{PLURAL:$1|1 stranicu|$1 stranica}}, bez stranica za razgovor.',
index 90cb83d..2b8223d 100644 (file)
@@ -715,7 +715,7 @@ Zo by přizjewjenje skónčił, dyrbiš tu nowe hesło postajić:',
 'resetpass-temp-password' => 'Nachwilne hesło:',
 'resetpass-abort-generic' => 'Měnjenje hesła je so přez rozšěrjenje přetorhnyło.',
 'resetpass-expired' => 'Twoje hesło je spadnyło. Prošu postaj nowe hesło za přizjewjenje.',
-'resetpass-expired-soft' => 'Twoje hesło je spadnyło a dyrbi so wróćo stajić. Prošu wubjer nětko druhe hesło abo klikń na "Přetorhnyć", zo by jo pozdźišo wróćo stajił.',
+'resetpass-expired-soft' => 'Twoje hesło je spadnyło a dyrbi so wróćo stajić. Prošu wubjer nětko druhe hesło abo klikń na "{{int:resetpass-submit-cancel}}", zo by jo pozdźišo wróćo stajił.',
 
 # Special:PasswordReset
 'passwordreset' => 'Hesło wróćo stajić',
@@ -1545,7 +1545,7 @@ Tuta informacija budźe zjawna.',
 'recentchanges-legend-heading' => "'''Legenda:'''",
 'recentchanges-legend-newpage' => '(hlej tež [[Special:NewPages|lisćinu nowych stronow]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Deleka so změny wot '''$2''' pokazuja (hač k '''$1''').",
+'rcnotefrom' => 'Deleka so změny wot <strong>$2</strong> pokazuja (hač k <strong>$1</strong>).',
 'rclistfrom' => 'Nowe změny pokazać, započinajo z $1',
 'rcshowhideminor' => 'snadne změny $1',
 'rcshowhideminor-show' => 'Pokazać',
@@ -2505,6 +2505,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Tuta IP-adresa je tuchwilu zablokowana.
 Najnowši zapisk w protokolu blokowanjow so deleka jako referenca podawa:',
 'sp-contributions-search' => 'Přinoški pytać',
+'sp-contributions-suppresslog' => 'potłóčene wužiwarske přinoški',
 'sp-contributions-username' => 'IP-adresa abo wužiwarske mjeno:',
 'sp-contributions-toponly' => 'Jenož wyše wersije pokazać',
 'sp-contributions-newonly' => 'Jenož změny pokazać, kotrež su wutworjenja stronow',
index 1e94beb..ce10c35 100644 (file)
@@ -880,7 +880,7 @@ Lehet, hogy már sikeresen megváltoztattad a jelszavad, vagy pedig időközben
 'resetpass-temp-password' => 'Ideiglenes jelszó:',
 'resetpass-abort-generic' => 'A jelszómódosítást megszakította egy kiterjesztés.',
 'resetpass-expired' => 'A jelszavad lejárt. Adjál meg egy új jelszót a bejelentkezéshez!',
-'resetpass-expired-soft' => 'A jelszavad lejárt, ezért újat kell beállítanod. Válassz most egy új jelszót, kattints a Mégse gombra, ha később akarod csak beállítani.',
+'resetpass-expired-soft' => 'A jelszavad lejárt, ezért újat kell beállítanod. Válassz most egy új jelszót, vagy kattints a {{int:resetpass-submit-cancel}} gombra, ha később akarod csak beállítani.',
 
 # Special:PasswordReset
 'passwordreset' => 'Jelszó törlése',
index 45bce2a..de8beed 100644 (file)
@@ -301,7 +301,7 @@ $messages = array(
 'tog-shownumberswatching' => 'Ցույց տալ էջ հսկող մասնակիցների թիվը',
 'tog-oldsig' => 'Ներկայիս ստորագրությունն է․',
 'tog-fancysig' => 'Ստորագրությունը վիքիտեքստի տեսքով (առանց ավտոմատ հղման)',
-'tog-uselivepreview' => 'Õ\95Õ£Õ¿Õ¡Õ£Õ¸Ö\80Õ®Õ¥Õ¬ Õ¸Ö\82Õ²Õ«Õ² Õ¶Õ¡Õ­Õ¡Õ¤Õ«Õ¿Õ¸Ö\82Õ´ (JavaScript) (Õ\93որձնական)',
+'tog-uselivepreview' => 'Õ\95Õ£Õ¿Õ¡Õ£Õ¸Ö\80Õ®Õ¥Õ¬ Õ¡Õ¶Õ´Õ«Õ»Õ¡Õ¯Õ¡Õ¶ Õ¶Õ¡Õ­Õ¡Õ¤Õ«Õ¿Õ¸Ö\82Õ´, Õ¡Õ¼Õ¡Õ¶Ö\81 Õ§Õ»Õ¨ Õ¾Õ¥Ö\80Õ¢Õ¥Õ¼Õ¶Õ¥Õ¬Õ¸Ö\82 (Ö\83որձնական)',
 'tog-forceeditsummary' => 'Նախազգուշացնել խմբագրման ամփոփումը դատարկ թողնելու դեպքում',
 'tog-watchlisthideown' => 'Թաքցնել իմ խմբագրումները հսկացանկից',
 'tog-watchlisthidebots' => 'Թաքցնել բոտերի խմբագրումները հսկացանկից',
@@ -317,7 +317,7 @@ $messages = array(
 
 'underline-always' => 'Միշտ',
 'underline-never' => 'Երբեք',
-'underline-default' => 'Օգտագործել զննարկիչի նախընտրությունները',
+'underline-default' => 'Դիտարկչի կամ թեմայի լռելյայն ոճով',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Խմբագրման շրջանի տառատեսակի ձևը.',
@@ -513,7 +513,7 @@ $1',
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).
 'aboutsite' => '{{grammar:genitive|{{SITENAME}}}} մասին',
 'aboutpage' => 'Project:Էությունը',
-'copyright' => 'Ô¿Õ¡ÕµÖ\84Õ« Õ¢Õ¸Õ¾Õ¡Õ¶Õ¤Õ¡Õ¯Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶Õ¨ Õ£Õ¿Õ¶Õ¾Õ¸Ö\82Õ´ Õ§ Â«$1» Õ¡Ö\80Õ¿Õ¸Õ¶Õ¡Õ£Ö\80Õ« Õ¿Õ¡Õ¯։',
+'copyright' => 'Ô¿Õ¡ÕµÖ\84Õ« Õ¢Õ¸Õ¾Õ¡Õ¶Õ¤Õ¡Õ¯Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶Õ¨ Õ©Õ¸Õ²Õ¡Ö\80Õ¯Õ¾Õ¡Õ® Õ§ $1 Õ©Õ¸Ö\82ÕµÕ¬Õ¡Õ¿Ö\80Õ¡Õ£Ö\80Õ¸Õ¾, Õ¥Õ©Õ¥ Õ¡ÕµÕ¬ Õ¢Õ¡Õ¶ Õ¶Õ·Õ¾Õ¡Õ® Õ¹Õ§։',
 'copyrightpage' => '{{ns:project}}:Հեղինակային իրավունքներ',
 'currentevents' => 'Ընթացիկ իրադարձություններ',
 'currentevents-url' => 'Project:Ընթացիկ իրադարձություններ',
@@ -634,7 +634,7 @@ $1',
 'cannotdelete-title' => 'Հնարավոր չէ ջնջել $1 էջը',
 'badtitle' => 'Անընդունելի անվանում',
 'badtitletext' => 'Հարցված էջի անվանումը անընդունելի է, դատարկ է կամ սխալ միջ-լեզվական կամ ինտերվիքի անվանում է։ Հնարավոր է, որ այն պարունակում է անթույլատրելի սիմվոլներ։',
-'perfcached' => 'Õ\80Õ¥Õ¿Ö\87ÕµÕ¡Õ¬ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö\80Õ¨ Õ¾Õ¥Ö\80Ö\81Õ¾Õ¡Õ® Õ¥Õ¶ Ö\84Õ¥Õ·Õ«Ö\81 և հնարավոր է չարտացոլեն վերջին փոփոխությունները։ Առավելագույն {{PLURAL:$1|արդյունք|$1 արդյունք}} է հասանելի քեշում։',
+'perfcached' => 'Õ\8dÕ¿Õ¸Ö\80Ö\87 Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö\80Õ¨ ÕºÕ¡Õ°Õ¸Ö\82Õ½Õ¿Õ¡Õ¾Õ¸Ö\80Õ¾Õ¡Õ® Õ¥Õ¶ և հնարավոր է չարտացոլեն վերջին փոփոխությունները։ Առավելագույն {{PLURAL:$1|արդյունք|$1 արդյունք}} է հասանելի քեշում։',
 'perfcachedts' => 'Հետևյալ տվյալները վերցված են քեշից և վերջին անգամ թարմացվել են $1։ A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.',
 'querypage-no-updates' => 'Այս էջի փոփոխությունները ներկայումս արգելված են։ Այստեղի տվյալները այժմ չեն թարմացվի։',
 'viewsource' => 'Դիտել վիքիկոդը',
@@ -782,6 +782,9 @@ $2',
 'login-throttled' => 'Դուք կատարել եք չափից շատ մուտքի փորձ։
 Խնդրում ենք սպասել որոշ ժամանակ կրկին փորձելուց առաջ։',
 'loginlanguagelabel' => 'Լեզու՝ $1',
+'pt-login' => 'Մտնել',
+'pt-createaccount' => 'Ստեղծել մասնակցի հաշիվ',
+'pt-userlogout' => 'Դուրս գալ',
 
 # Email sending
 'php-mail-error-unknown' => 'Անհայտ սխալ PHP-ի mail() ֆունկցիայում',
@@ -1074,8 +1077,8 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 (նախ) = համեմատել նախորդ տարբերակի հետ,<br />'''չ''' = չնչին խմբագրում",
 'history-fieldset-title' => 'Դիտել պատմությունը',
 'history-show-deleted' => 'Միայն ջնջված',
-'histfirst' => 'Առաջին',
-'histlast' => 'Õ\8eÕ¥Ö\80Õ»Õ«Õ¶',
+'histfirst' => 'ամենահին',
+'histlast' => 'Õ¡Õ´Õ¥Õ¶Õ¡Õ©Õ¡Ö\80Õ´',
 'historysize' => '({{PLURAL:$1|1 բայթ|$1 բայթ}})',
 'historyempty' => '(դատարկ)',
 
@@ -1088,9 +1091,10 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 Փորձեք [[Special:Search|որոնել վիքիում]] նոր համանման էջեր։',
 
 # Revision deletion
-'rev-deleted-comment' => '(Õ´Õ¥Õ¯Õ¶Õ¡Õ¢Õ¡Õ¶Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶ը հեռացված է)',
+'rev-deleted-comment' => '(Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ´Õ¡Õ¶ Õ¡Õ´Ö\83Õ¸Ö\83Õ¸Ö\82Õ´ը հեռացված է)',
 'rev-deleted-user' => '(մասնակցի անունը ջնջված է)',
 'rev-deleted-event' => '(գրությունը հեռացված է)',
+'rev-deleted-user-contribs' => '[մասնակցի անունը կամ ԱյՊի հասցեն հեռացված է, խմբագրումը թաքցված է ներդրումներից]',
 'rev-deleted-text-permission' => 'Էջի այս տարբերակը հեռացված է։
 Հնարավոր է մանրամասնություններ լինեն [{{fullurl:{{ns:special}}:Log/delete|page={{PAGENAMEE}}}} ջնջման տեղեկամատյանում]։',
 'rev-deleted-text-view' => "Էջի այս տարբերակը '''ջնջված''' է։
@@ -1122,13 +1126,15 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'revdelete-hide-user' => 'Թաքցնել հեղինակի մասնակցի անունը/IP',
 'revdelete-hide-restricted' => 'Թաքցնել տվյալները և՛ ադմինիստրատորներից, և՛ այլ մասնակիցներից',
 'revdelete-radio-same' => '(չի կարելի խմբագրել)',
-'revdelete-radio-set' => 'Ô±ÕµÕ¸',
-'revdelete-radio-unset' => 'Õ\88Õ¹',
+'revdelete-radio-set' => 'Ô¹Õ¡Ö\84Ö\81Õ¾Õ¡Õ®',
+'revdelete-radio-unset' => 'Õ\8fÕ¥Õ½Õ¡Õ¶Õ¥Õ¬Õ«',
 'revdelete-suppress' => 'Թաքցնել տվյալները ադմինիստրատորներից և մյուսներից նոյնպես',
 'revdelete-unsuppress' => 'Հանել սահմանափակումները վերականգնված տարբերակներից',
 'revdelete-log' => 'Պատճառ.',
 'revdelete-submit' => 'Կիրառել ընտրված {{PLURAL:$1|տարբերակի|տարբերակների}} վրա',
 'revdelete-success' => "'''Տարբերակի տեսանելիությունը բարեհաջող թարմացված է։'''",
+'revdelete-failure' => '<strong>Խմբագրման տեսանելիություն հնարավոր չէր փոփոխել՝</strong>
+$1',
 'logdelete-success' => "'''Իրադարձության տեսանելիությունը փոփոխված է։'''",
 'revdel-restore' => 'Փոխել տեսանելիությունը',
 'pagehist' => 'Էջի պատմություն',
@@ -1153,6 +1159,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'compareselectedversions' => 'Համեմատել ընտրած տարբերակները',
 'showhideselectedversions' => 'Ցուցադրել/թաքցնել ընտրված խմբագրումները',
 'editundo' => 'հետ շրջել',
+'diff-empty' => '(Տարբերություն չկա)',
 
 # Search results
 'searchresults' => 'Որոնման արդյունքներ',
@@ -1254,7 +1261,7 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'timezoneregion-indian' => 'Հնդկական Օվկիանոս',
 'timezoneregion-pacific' => 'Խաղաղ օվկիանոս',
 'allowemail' => 'Թույլատրել էլ-նամակներ մյուս մասնակիցներից',
-'prefs-searchoptions' => 'Õ\88Ö\80Õ¸Õ¶Õ´Õ¡Õ¶ Õ¨Õ¶Õ¿Ö\80Õ¡Õ¶Ö\84Õ¶Õ¥Ö\80',
+'prefs-searchoptions' => 'Õ\88Ö\80Õ¸Õ¶Õ¸Ö\82Õ´',
 'prefs-namespaces' => 'Անվանատարածք',
 'defaultns' => 'Հակառակ դեպքում, որոնել այս անվանատարծքներում․',
 'default' => 'լռությամբ',
@@ -1392,11 +1399,23 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'rcnotefrom' => "Ստորև բերված են փոփոխությունները սկսած՝ '''$2''' (մինչև՝ '''$1''')։",
 'rclistfrom' => 'Ցույց տալ նոր փոփոխությունները սկսած $1',
 'rcshowhideminor' => '$1 չնչին խմբագրումները',
+'rcshowhideminor-show' => 'Ցուցադրել',
+'rcshowhideminor-hide' => 'Թաքցնել',
 'rcshowhidebots' => '$1 բոտերին',
+'rcshowhidebots-show' => 'Ցուցադրել',
+'rcshowhidebots-hide' => 'Թաքցնել',
 'rcshowhideliu' => '$1 մուտք գործած մասնակիցներին',
+'rcshowhideliu-show' => 'Ցուցադրել',
+'rcshowhideliu-hide' => 'Թաքցնել',
 'rcshowhideanons' => '$1 անանուն մասնակիցներին',
+'rcshowhideanons-show' => 'Ցուցադրել',
+'rcshowhideanons-hide' => 'Թաքցնել',
 'rcshowhidepatr' => '$1 ստուգված խմբագրումները',
+'rcshowhidepatr-show' => 'Ցուցադրել',
+'rcshowhidepatr-hide' => 'Թաքցնել',
 'rcshowhidemine' => '$1 իմ խմբագրումները',
+'rcshowhidemine-show' => 'Ցուցադրել',
+'rcshowhidemine-hide' => 'Թաքցնել',
 'rclinks' => 'Ցույց տալ վերջին $1 փոփոխությունները վերջին $2 օրվա ընթացքում<br />$3',
 'diff' => 'տարբ',
 'hist' => 'պատմ',
@@ -1410,8 +1429,9 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 '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»',
 
 # Recent changes linked
 'recentchangeslinked' => 'Կապված փոփոխություններ',
index d111b8f..0e4159c 100644 (file)
@@ -730,7 +730,7 @@ Pro completar le accesso, tu debe definir un nove contrasigno hic:',
 'resetpass-temp-password' => 'Contrasigno temporari:',
 'resetpass-abort-generic' => 'Le cambio del contrasigno ha essite abortate per un extension.',
 'resetpass-expired' => 'Le contrasigno ha expirate. Per favor defini un nove contrasigno pro aperir session.',
-'resetpass-expired-soft' => 'Le contrasigno ha expirate e debe esser redefinite. Per favor elige un nove contrasigno ora, o clicca sur Cancellar pro redefinir lo plus tarde.',
+'resetpass-expired-soft' => 'Le contrasigno ha expirate e debe esser redefinite. Per favor elige un nove contrasigno ora, o clicca sur "{{int:resetpass-submit-cancel}}" pro redefinir lo plus tarde.',
 
 # Special:PasswordReset
 'passwordreset' => 'Reinitialisar contrasigno',
@@ -2478,10 +2478,10 @@ Ecce le configurationes actual del pagina '''$1''':",
 Ecce le configurationes actual del pagina '''$1''':",
 'protect-cascadeon' => 'Iste pagina es actualmente protegite proque illo es includite in le sequente {{PLURAL:$1|pagina, le qual|paginas, le quales}} ha activate le protection in cascada.
 Tu pote cambiar le nivello de protection de iste pagina, ma isto non cambiara le effecto del protection in cascada.',
-'protect-default' => 'Permitter tote le usatores',
-'protect-fallback' => 'Permitter solmente usatores con le permission de "$1"',
-'protect-level-autoconfirmed' => 'Permitter solmente usatores autoconfirmate',
-'protect-level-sysop' => 'Permitter solmente administratores',
+'protect-default' => 'Permitter tote le usatores',
+'protect-fallback' => 'Permitter solmente al usatores con le privilegio de "$1"',
+'protect-level-autoconfirmed' => 'Permitter solmente al usatores autoconfirmate',
+'protect-level-sysop' => 'Permitter solmente al administratores',
 'protect-summary-cascade' => 'in cascada',
 'protect-expiring' => 'expira le $1 (UTC)',
 'protect-expiring-local' => 'expira le $1',
@@ -3108,7 +3108,7 @@ Le causa es probabilemente un ligamine verso un sito externe que es presente in
 '''NON''' completa isto!",
 
 # Info page
-'pageinfo-title' => 'Informationes pro "$1"',
+'pageinfo-title' => 'Information sur "$1"',
 'pageinfo-not-current' => 'Regrettabilemente, il es impossibile fornir iste information pro versiones ancian.',
 'pageinfo-header-basic' => 'Information de base',
 'pageinfo-header-edits' => 'Historia de modificationes',
index 29e3636..0aa55c6 100644 (file)
@@ -621,7 +621,7 @@ Tapno malpas ti panagserrek, nasken a mangiyasentarka ti baro a kontrasenias dit
 'resetpass-temp-password' => 'Temporario a kontrasenias:',
 'resetpass-abort-generic' => 'Ti panagsukat ti kontrasenias ket pinasardeng babaen ti maysa a pagpaatiddog.',
 'resetpass-expired' => 'Nagpason ti kontraseniasmo. Pangngaasi a mangiyasentar ti baro a kontrasenias tapno makastrek.',
-'resetpass-expired-soft' => 'Nagpason ti kontraseniasmo, ken nasken a maiyasentar manen. Pangngaasi nga agpili tattan ti baro a kontrasenias, wenno pinduten ti ukasen tapno iyasentar no madamdama.',
+'resetpass-expired-soft' => 'Nagpason ti kontraseniasmo, ken nasken a maiyasentar manen. Pangngaasi nga agpili tattan ti baro a kontrasenias, wenno pinduten ti "{{int:resetpass-submit-cancel}}"  tapno maiyasentarto intono madamdama.',
 
 # Special:PasswordReset
 'passwordreset' => 'Iyasentar manen ti kontrasenias',
@@ -1491,14 +1491,26 @@ Ti esurat a pagtaengam ket saan a maipakita kadagiti agar-aramat nga agkontak ke
 'recentchanges-label-plusminus' => 'Ti panagbaliw ti kadakkel ti panid babaen ti bilang dagiti byte',
 'recentchanges-legend-heading' => "'''Sarita:'''",
 'recentchanges-legend-newpage' => '(kitaen pay ti [[Special:NewPages|listaan ti baro a pampanid]])',
-'rcnotefrom' => "Dita baba ket dagiti sinukatan manipud idi '''$2''' (agingga iti '''$1''' a naipakita).",
+'rcnotefrom' => 'Dita baba ket dagiti sinukatan manipud idi strong>$2</strong> (agingga iti <strong>$1</strong> a naipakita).',
 'rclistfrom' => 'Ipakita dagiti kabarbaro a sinukatan a mangrugi manipud idi $1',
 'rcshowhideminor' => '$1 dagiti bassit a panag-urnos',
+'rcshowhideminor-show' => 'Ipakita',
+'rcshowhideminor-hide' => 'Ilemmeng',
 'rcshowhidebots' => '$1 dagiti bot',
+'rcshowhidebots-show' => 'Ipakita',
+'rcshowhidebots-hide' => 'Ilemmeng',
 'rcshowhideliu' => '$1 dagiti nakarehistro nga agar-aramat',
+'rcshowhideliu-show' => 'Ipakita',
+'rcshowhideliu-hide' => 'Ilemmeng',
 'rcshowhideanons' => '$1 dagiti di am-ammo nga agar-aramat',
+'rcshowhideanons-show' => 'Ipakita',
+'rcshowhideanons-hide' => 'Ilemmeng',
 'rcshowhidepatr' => '$1 dagiti napatrulian a panag-urnos',
+'rcshowhidepatr-show' => 'Ipakita',
+'rcshowhidepatr-hide' => 'Ilemmeng',
 'rcshowhidemine' => '$1 dagiti inurnosko',
+'rcshowhidemine-show' => 'Ipakita',
+'rcshowhidemine-hide' => 'Ilemmeng',
 'rclinks' => 'Ipakita dagiti naudi a $1 a sinukatan iti kallabes a $2 nga al-aldaw<br />$3',
 'diff' => 'sabali',
 'hist' => 'saritaan',
@@ -1633,6 +1645,7 @@ Nasken nga agdamagka ti addaan ti abilidad a mangkita ti nalapdan a datos ti pap
 'php-uploaddisabledtext' => 'Ti pinag-ipan ti papeles ket naiddep idiay PHP.
 Panngaasi a kitaem ti pannakaikabil ti pinag-ipan ti papeles.',
 'uploadscripted' => 'Daytoy a papeles ket adda nagyanna a HTML wenno panagsurat a kodigo a mabalin nga agpakamali ti panagbasa ti sapot a pagbasabasa.',
+'uploadscriptednamespace' => 'Daytoy a papeles ti SVG ket aglaon ti maysa a saan a mabalin a nagan ti espasio ti "$1"',
 'uploadinvalidxml' => 'Ti XML iti naikarga a papeles ket saan a maiwaswas.',
 'uploadvirus' => 'Addaan ti birus daytoy a papeles! Salaysay: $1',
 'uploadjava' => 'Daytoy a papeles ket ZIP a papeles nga adda nagyanna a Java .a kita ti papeles.
@@ -2463,8 +2476,10 @@ Ti naudi a listaan ti pannakaserra ket adda dita baba tapno mausar a reperensia:
 'sp-contributions-blocked-notice-anon' => 'Daytoy nga IP a pagtaengan ket naserraan.
 Ti naudi a listaan ti pannakaserra ket adda dita baba tapno mausar a reperensia:',
 'sp-contributions-search' => 'Agsapul para kadagiti naar-aramid',
+'sp-contributions-suppresslog' => 'pasardengen dagiti kontribusion ti agar-aramat',
 'sp-contributions-username' => 'IP a pagtaengan wenno nagan ti agar-aramat:',
 'sp-contributions-toponly' => 'Ipakita laeng dagiti inurnos a kinaudian a panagbaliw',
+'sp-contributions-newonly' => 'Ipakita laeng dagiti inurnos a pannakapartuat ti pampanid',
 'sp-contributions-submit' => 'Biruken',
 
 # What links here
index ee61e0d..d74ed9d 100644 (file)
@@ -762,6 +762,7 @@ Vinsamlegast bíðið $1 áður en þú reynir aftur.',
 'loginlanguagelabel' => 'Tungumál: $1',
 'suspicious-userlogout' => 'Beiðni um útskráningu hafnað því hún var líklegast send frá biluðum vafra eða vefseli sem hefur vistað vefsíðuna í flýtiminni.',
 'createacct-another-realname-tip' => 'Alvöru nafn er valfrjálst. Ef þú kýst að gefa það upp, verður það notað til að gefa þér heiður af verkum þínum.',
+'pt-createaccount' => 'Stofna aðgang',
 
 # Email sending
 'php-mail-error-unknown' => 'Óþekkt villa í PHP mail() aðgerð.',
@@ -1621,11 +1622,23 @@ Tölvupóstfang þitt er ekki gefið upp þegar aðrir notendur hafa samband vi
 'rcnotefrom' => "Að neðan eru breytingar síðan '''$2''' (allt að '''$1''' sýndar).",
 'rclistfrom' => 'Sýna breytingar frá og með $1',
 'rcshowhideminor' => '$1 minniháttar breytingar',
+'rcshowhideminor-show' => 'Sýna',
+'rcshowhideminor-hide' => 'Fela',
 'rcshowhidebots' => '$1 vélmenni',
+'rcshowhidebots-show' => 'Sýna',
+'rcshowhidebots-hide' => 'Fela',
 'rcshowhideliu' => '$1 skráðir notendur',
+'rcshowhideliu-show' => 'Sýna',
+'rcshowhideliu-hide' => 'Fela',
 'rcshowhideanons' => '$1 óinnskráða notendur',
+'rcshowhideanons-show' => 'Sýna',
+'rcshowhideanons-hide' => 'Fela',
 'rcshowhidepatr' => '$1 vaktaðar breytingar',
+'rcshowhidepatr-show' => 'Sýna',
+'rcshowhidepatr-hide' => 'Fela',
 'rcshowhidemine' => '$1 mínar breytingar',
+'rcshowhidemine-show' => 'Sýna',
+'rcshowhidemine-hide' => 'Fela',
 'rclinks' => 'Sýna síðustu $1 breytingar síðustu $2 daga<br />$3',
 'diff' => 'breyting',
 'hist' => 'breytingaskrá',
index f0dd063..173e761 100644 (file)
@@ -862,7 +862,7 @@ La password potrebbe essere stata già cambiata, oppure potrebbe essere stata ri
 'resetpass-temp-password' => 'Password temporanea:',
 'resetpass-abort-generic' => "La modifica della password è stata interrotta da un'estensione.",
 'resetpass-expired' => "La password è scaduta. Si prega di impostare una nuova password per effettuare l'accesso.",
-'resetpass-expired-soft' => 'La tua password è scaduta e deve essere reimpostata. Si prega di scegliere una nuova password o fare clic su annulla per reimpostarla successivamente.',
+'resetpass-expired-soft' => 'La tua password è scaduta e deve essere reimpostata. Si prega di scegliere una nuova password o fare clic su "{{int:resetpass-submit-cancel}}" per reimpostarla successivamente.',
 
 # Special:PasswordReset
 'passwordreset' => 'Reimposta password',
@@ -1695,7 +1695,7 @@ Il tuo indirizzo non viene rivelato quando gli altri utenti ti contattano.',
 'recentchanges-legend-heading' => "'''Legenda:'''",
 'recentchanges-legend-newpage' => "(vedi anche [[Special:NewPages|l'elenco delle nuove pagine]])",
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Di seguito sono elencate le modifiche apportate a partire da '''$2''' (fino a '''$1''').",
+'rcnotefrom' => 'Di seguito sono elencate le modifiche apportate a partire da <strong>$2</strong> (mostrate fino a <strong>$1</strong>).',
 'rclistfrom' => 'Mostra le modifiche apportate a partire da $1',
 'rcshowhideminor' => '$1 le modifiche minori',
 'rcshowhideminor-show' => 'Mostra',
@@ -2204,7 +2204,7 @@ I redirect <del>cancellati</del> sono stati corretti.',
 'protectedpages-timestamp' => 'Data e ora',
 'protectedpages-page' => 'Pagina',
 'protectedpages-expiry' => 'Scadenza',
-'protectedpages-performer' => "Protezione dell'utente",
+'protectedpages-performer' => "Protetta dall'utente",
 'protectedpages-params' => 'Parametri di protezione',
 'protectedpages-reason' => 'Motivo',
 'protectedpages-unknown-timestamp' => 'Sconosciuto',
@@ -2651,6 +2651,7 @@ $1',
 'sp-contributions-blocked-notice' => "Questo utente è attualmente bloccato. L'ultimo elemento del registro dei blocchi è riportato di seguito per informazione:",
 'sp-contributions-blocked-notice-anon' => "Questo indirizzo IP è attualmente bloccato. Di seguito è riportato l'ultimo elemento del registro dei blocchi:",
 'sp-contributions-search' => 'Ricerca contributi',
+'sp-contributions-suppresslog' => 'contributi utente soppressi',
 'sp-contributions-username' => 'Indirizzo IP o nome utente:',
 'sp-contributions-toponly' => 'Mostra solo i contributi che sono le ultime revisioni per la pagina',
 'sp-contributions-newonly' => 'Visualizza solo le modifiche che sono creazioni di pagina',
index a802831..da90527 100644 (file)
@@ -958,7 +958,7 @@ $1待ってから再度試してください。',
 'resetpass-temp-password' => '仮パスワード:',
 'resetpass-abort-generic' => '拡張機能により、パスワードの変更は取り消されました。',
 'resetpass-expired' => 'パスワードの有効期限が切れました。ログインするには新しいパスワードを設定してください。',
-'resetpass-expired-soft' => 'ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\81®æ\9c\89å\8a¹æ\9c\9fé\99\90ã\81\8cå\88\87ã\82\8cã\81\9fã\81\9fã\82\81ã\80\81å\86\8d設å®\9aã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82æ\96°ã\81\97ã\81\84ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\82\92ä»\8aã\81\99ã\81\90設å®\9aã\81\99ã\82\8bã\81\8bã\80\81ã\81¾ã\81\9fã\81¯ã\82­ã\83£ã\83³ã\82»ã\83«をクリックしてあとで再設定してください。',
+'resetpass-expired-soft' => 'ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\81®æ\9c\89å\8a¹æ\9c\9fé\99\90ã\81\8cå\88\87ã\82\8cã\81\9fã\81\9fã\82\81ã\80\81å\86\8d設å®\9aã\81\99ã\82\8bå¿\85è¦\81ã\81\8cã\81\82ã\82\8aã\81¾ã\81\99ã\80\82æ\96°ã\81\97ã\81\84ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\82\92ä»\8aã\81\99ã\81\90設å®\9aã\81\99ã\82\8bã\81\8bã\80\81ã\81¾ã\81\9fã\81¯ã\80\8c{{int:resetpass-submit-cancel}}ã\80\8dをクリックしてあとで再設定してください。',
 
 # Special:PasswordReset
 'passwordreset' => 'パスワードの再設定',
@@ -1509,7 +1509,7 @@ $1',
 'searchrelated' => '関連',
 'searchall' => 'すべて',
 'showingresults' => '<strong>$2</strong> 件目以降の最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。',
-'showingresultsinrange' => '<strong>$2</strong> 件目以降の最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。',
+'showingresultsinrange' => '<strong>$2</strong> 件目から<strong>$3</strong> 件目までの範囲内で最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。',
 'showingresultsnum' => '<strong>$2</strong> 件目以降の {{PLURAL:$3|<strong>$3</strong> 件の結果}}を表示しています。',
 'showingresultsheader' => '「<strong>$4</strong>」の検索結果 {{PLURAL:$5|<strong>$3</strong> 件中の <strong>$1</strong> 件目|<strong>$3</strong> 件中の <strong>$1</strong> 件目から <strong>$2</strong> 件目}}',
 'search-nonefound' => '問い合わせに合致する検索結果はありませんでした。',
@@ -1837,7 +1837,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'recentchanges-legend-newpage' => '([[Special:NewPages|新しいページ一覧]]も参照)',
 'recentchanges-legend-plusminus' => '(<em>±123</em>)',
 'rcnotefrom' => '以下は<strong>$2</strong>以降の更新です (最大 <strong>$1</strong> 件)。',
-'rclistfrom' => '$1以降の更新を表示する',
+'rclistfrom' => '$2 $3以降の更新を表示する',
 'rcshowhideminor' => '細部の編集を$1',
 'rcshowhideminor-show' => '表示',
 'rcshowhideminor-hide' => '非表示',
@@ -2380,6 +2380,7 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'protectedpages-page' => 'ページ',
 'protectedpages-expiry' => '有効期限',
 'protectedpages-performer' => '保護の実行者',
+'protectedpages-params' => '保護のパラメーター',
 'protectedpages-reason' => '理由',
 'protectedpages-unknown-timestamp' => '不明',
 'protectedpages-unknown-performer' => '不明な利用者',
@@ -2846,6 +2847,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'このIPアドレスは現在ブロックされています。
 参考のために最近のブロック記録項目を以下に表示します:',
 'sp-contributions-search' => '投稿の検索',
+'sp-contributions-suppresslog' => '利用者の秘匿された投稿',
 'sp-contributions-username' => 'IPアドレスまたは利用者名:',
 'sp-contributions-toponly' => '最新版の編集のみを表示',
 'sp-contributions-newonly' => 'ページ作成を伴う編集のみを表示',
@@ -3202,7 +3204,7 @@ $2',
 一時フォルダーがありません。',
 'import-parse-failure' => 'XML取り込みの構文解析に失敗しました',
 'import-noarticle' => '取り込むページがありません!',
-'import-nonewrevisions' => 'すべての版は以前に取り込み済みです。',
+'import-nonewrevisions' => '版のインポートはされませんでした(すべての版が以前に取り込み済みだったか、エラーにより飛ばされたため)。',
 'xml-error-string' => '$1、$2 行の $3 文字目 ($4バイト目): $5',
 'import-upload' => 'XMLデータをアップロード',
 'import-token-mismatch' => 'セッションデータを損失しました。
index 670622c..5c2af8a 100644 (file)
@@ -19,6 +19,7 @@
  * @author Malafaya
  * @author Nemo bis
  * @author Nodar Kherkheulidze
+ * @author Otogi
  * @author Reedy
  * @author Sopho
  * @author Temuri rajavi
@@ -1215,7 +1216,7 @@ $1",
 
 # Search results
 'searchresults' => 'ძიების შედეგები',
-'searchresults-title' => 'ძიების შედეგები "$1"',
+'searchresults-title' => 'ძიების შედეგები „$1“',
 'toomanymatches' => 'ნაპოვნია ძალიან ბევრი შესაბამისობა, ეცადეთ სხვა მოთხოვნა',
 'titlematches' => 'სტატიის სათაური შეესაბამება',
 'textmatches' => 'გვერდის ტექსტი შესაბამისია',
@@ -4061,11 +4062,18 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'rotate-comment' => 'სურათი მოტრიალებულია $1 {{PLURAL:$1|გრადუსით|გრადუსით}} საათის ისრის მიმართულებით',
 
 # Limit report
+'limitreport-title' => 'მონაცემების პროფილური ანალიზატორი:',
+'limitreport-cputime' => 'პროცესორის დროის გამოყენება',
 'limitreport-cputime-value' => '$1 {{PLURAL:$1|წამი}}',
 'limitreport-walltime' => 'რეალურ დროში გამოყენება',
 'limitreport-walltime-value' => '$1 {{PLURAL:$1|წამი}}',
+'limitreport-ppvisitednodes' => 'პრეპროცესორის მიერ მონახულებადი კვანძების რაოდენობა',
+'limitreport-postexpandincludesize' => 'ღია ჩართვების ზომა',
 'limitreport-postexpandincludesize-value' => '$1/$2 {{PLURAL:$2|ბაიტი}}',
+'limitreport-templateargumentsize' => 'თარგის არგუმენტის ზომა',
 'limitreport-templateargumentsize-value' => '$1/$2 {{PLURAL:$2|ბაიტი}}',
+'limitreport-expansiondepth' => 'გაფართოების უდიდესი სიღრმე',
+'limitreport-expensivefunctioncount' => 'ანალიზატორის „ძვირი“ ფუნქციის რაოდენობა',
 
 # Special:ExpandTemplates
 'expandtemplates' => 'გაშლილი თარგები',
index 555af82..c97e44b 100644 (file)
@@ -388,18 +388,19 @@ $messages = array(
 'tog-fancysig' => 'Қолтаңбаны уикимәтін ретінде қарастыру (автоматты сілтеме қойылмайды)',
 'tog-uselivepreview' => 'Тура қарап шығуды қолдану (сынақтық)',
 'tog-forceeditsummary' => 'Өңдеменің қысқаша мазмұндамасы бос қалғанда маған ескерт',
-'tog-watchlisthideown' => 'Өңдемелерімді бақылау тізімінен жасыр',
-'tog-watchlisthidebots' => 'Бот өңдемелерін бақылау тізімінен жасыр',
+'tog-watchlisthideown' => 'Өңдемелерімді бақылау тізімінен жасыру',
+'tog-watchlisthidebots' => 'Бот өңдемелерін бақылау тізімінен жасыру',
 'tog-watchlisthideminor' => 'Шағын өңдемелерді бақылау тізімінде көрсетпеу',
 'tog-watchlisthideliu' => 'Бақылау тізіміндегі қатысушылардың өңдеулерін көрсетпеу',
 'tog-watchlisthideanons' => 'Бақылау тізіміндегі жасырын қатысушылардың өңдеулерін көрсетпеу',
 'tog-watchlisthidepatrolled' => 'Бақылау тізімінде тексерілген өңдеулерді көрсетпеу',
 'tog-ccmeonemails' => 'Басқа қатысушыға жіберген хатымның көшірмесін маған да жөнелт',
-'tog-diffonly' => 'Ð\90йÑ\8bÑ\80ма Ð°Ñ\81Ñ\82Ñ\8bнда Ð±ÐµÑ\82 Ð¼Ð°Ò\93лұмаÑ\82Ñ\8bн ÐºÓ©Ñ\80Ñ\81еÑ\82пе',
+'tog-diffonly' => 'Ð\9dÒ±Ñ\81Ò\9bалаÑ\80 Ð°Ð¹Ñ\8bÑ\80маÑ\88Ñ\8bлÑ\8bÒ\9bÑ\82аÑ\80Ñ\8bнÑ\8bÒ£ Ð°Ñ\81Ñ\82Ñ\8bнда Ð±ÐµÑ\82 Ð¼Ð°Ò\93лұмаÑ\82Ñ\8bн ÐºÓ©Ñ\80Ñ\81еÑ\82пеÑ\83',
 'tog-showhiddencats' => 'Жасырын санаттарды көрсету',
 'tog-noconvertlink' => 'Сілтеме атауларын ауыстырма',
 'tog-norollbackdiff' => 'Шегіндіруден кейін нұсқалардың айырмашылығын көрсетпеу',
 'tog-useeditwarning' => 'Өңдемесі сақталмаған парақшадан шығар кезде ескерту',
+'tog-prefershttps' => 'Кірген кезде қауіпсіз байлануды әрқашан қолдану',
 
 'underline-always' => 'Әрқашан',
 'underline-never' => 'Ешқашан',
@@ -1433,6 +1434,7 @@ $1",
 'yourrealname' => 'Нақты атыңыз:',
 'yourlanguage' => 'Тіліңіз:',
 'yourvariant' => 'Жазба тілінің нұсқалары:',
+'prefs-help-variant' => 'Қалаған нұсқаңыз немесе орфография бұл уикидің контент беттерінде көрсетіледі.',
 'yournick' => 'Жаңа қолтаңбаңыз:',
 'prefs-help-signature' => 'Талқылау беттерінде хабарыңыздан кейін "<nowiki>~~~~</nowiki>" белгісін қалдырсаңыз, бұл қолтаңбаңызбен сол кездегі датаға ауыстырылады.',
 'badsig' => 'Қам қолтаңбаңыз жарамсыз; HTML белгішелерін тексеріңіз.',
@@ -1448,6 +1450,8 @@ $1",
 'prefs-help-realname' => 'Нақты атыңыз міндетті емес.
 Егер бұны жетістіруді таңдасаңыз, бұл түзетуіңіздің ауторлығын анықтау үшін қолданылады.',
 'prefs-help-email' => 'Электронды поштаңыздың мекенжайын көрсету міндетті емес, бірақ құпия сөзіңізді ұмытқан жағдайда керек болады.',
+'prefs-help-email-others' => 'Кейде қатысушы немесе талқылау бетіңізге е-пошта мекенжайы сілтемесін көрсету арқылы басқалармен байланыса аласыз.
+Е-пошта мекенжайыныңыз басқа қатысушылар сізбен байланысқан кезде көрсетілмейді',
 'prefs-help-email-required' => 'Е-пошта мекенжайы керек.',
 'prefs-info' => 'Негізгі мәлімет',
 'prefs-i18n' => 'Тіл туралы мәлімет',
@@ -1465,6 +1469,7 @@ $1",
 'prefs-displaysearchoptions' => 'Көрсету бапталымдары',
 'prefs-displaywatchlist' => 'Көрсету бапталымдары',
 'prefs-diffs' => 'Айырмашылықтар',
+'prefs-help-prefershttps' => 'Бұл баптауды келесі кіргеніңізде әсерін көре аласыз.',
 
 # User preference: email validation using jQuery
 'email-address-validity-invalid' => 'Жарамсыз электронды пошта мекен-жайын енгізіңіз',
@@ -1652,11 +1657,16 @@ $1",
 'rcnotefrom' => "Төменде '''$2''' кезінен бергі ('''$1''' жеткенше дейін) өзгерістер көрсетіледі.",
 'rclistfrom' => '$1 кезінен бергі жаңа өзгерістерді көрсет.',
 'rcshowhideminor' => 'Шағын өңдемелерді $1',
+'rcshowhideminor-hide' => 'жасыру',
 'rcshowhidebots' => 'Боттарды $1',
+'rcshowhidebots-show' => 'көрсету',
 'rcshowhideliu' => 'Тіркелгендерді $1',
+'rcshowhideliu-hide' => 'жасыру',
 'rcshowhideanons' => 'Кірмегендерді $1',
+'rcshowhideanons-hide' => 'жасыру',
 'rcshowhidepatr' => 'Зерттелген өңдемелерді $1',
 'rcshowhidemine' => 'Өңдемелерімді $1',
+'rcshowhidemine-hide' => 'жасыру',
 'rclinks' => 'Соңғы $2 күнде болған, соңғы $1 өзгерісті көрсет<br />$3',
 'diff' => 'айырм.',
 'hist' => 'тарихы',
@@ -2946,7 +2956,7 @@ $2',
 
 # Skin names
 'skinname-cologneblue' => 'Көк зеңгірлігі (cologneblue)',
-'skinname-monobook' => 'Ð\94аÑ\80а кітап (monobook)',
+'skinname-monobook' => 'Ð\96еке кітап (monobook)',
 'skinname-modern' => 'Заманауи (modern)',
 
 # Patrolling
@@ -3536,7 +3546,7 @@ $5
 'iranian-calendar-m9' => 'азар',
 'iranian-calendar-m10' => 'ди',
 'iranian-calendar-m11' => 'бемін',
-'iranian-calendar-m12' => 'аспанд',
+'iranian-calendar-m12' => 'аспанд (Иран күнтізбесі)',
 
 # Hebrew month names
 'hebrew-calendar-m1' => 'тішри',
@@ -3546,7 +3556,7 @@ $5
 'hebrew-calendar-m5' => 'шыбат',
 'hebrew-calendar-m6' => 'адар',
 'hebrew-calendar-m6a' => 'адар',
-'hebrew-calendar-m6b' => 'уадар',
+'hebrew-calendar-m6b' => 'Адар II (иврит күнтізбесі)',
 'hebrew-calendar-m7' => 'нисан',
 'hebrew-calendar-m8' => 'аяр',
 'hebrew-calendar-m9' => 'сиуан',
index 533b122..50665d5 100644 (file)
@@ -946,7 +946,7 @@ $1 뒤에 다시 시도하세요.',
 'resetpass-temp-password' => '임시 비밀번호:',
 'resetpass-abort-generic' => '비밀번호 바꾸기가 확장 기능에 의해 중단되었습니다.',
 'resetpass-expired' => '비밀번호가 만료되었습니다. 로그인하려면 새로운 비밀번호를 설정해야 합니다.',
-'resetpass-expired-soft' => '비밀번호가 만료되어 재설정해야 합니다. 지금 새로운 비밀번호를 선택하거나, 취소를 클릭하고 나중에 재설정해주세요.',
+'resetpass-expired-soft' => '비밀번호가 만료되어 재설정해야 합니다. 지금 새로운 비밀번호를 선택하거나, "{{int:resetpass-submit-cancel}}"를 클릭하고 나중에 재설정해주세요.',
 
 # Special:PasswordReset
 'passwordreset' => '비밀번호 재설정',
@@ -1815,14 +1815,26 @@ HTML 태그를 확인하세요.',
 'recentchanges-legend-heading' => "'''범례:'''",
 'recentchanges-legend-newpage' => '([[Special:NewPages|새 문서 목록]]도 보세요)',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "다음은 '''$2'''에서부터 바뀐 문서 '''$1'''개입니다.",
+'rcnotefrom' => '다음은 <strong>$2</strong>에서부터 바뀐 문서 <strong>$1</strong>개입니다.',
 'rclistfrom' => '$1 이래로 새로 바뀐 문서 보기',
 'rcshowhideminor' => '사소한 편집을 $1',
+'rcshowhideminor-show' => '보이기',
+'rcshowhideminor-hide' => '숨기기',
 'rcshowhidebots' => '봇을 $1',
+'rcshowhidebots-show' => '보이기',
+'rcshowhidebots-hide' => '숨기기',
 'rcshowhideliu' => '등록된 사용자를 $1',
+'rcshowhideliu-show' => '보이기',
+'rcshowhideliu-hide' => '숨기기',
 'rcshowhideanons' => '익명 사용자를 $1',
+'rcshowhideanons-show' => '보이기',
+'rcshowhideanons-hide' => '숨기기',
 'rcshowhidepatr' => '순찰된 편집을 $1',
+'rcshowhidepatr-show' => '보이기',
+'rcshowhidepatr-hide' => '숨기기',
 'rcshowhidemine' => '내 편집을 $1',
+'rcshowhidemine-show' => '보이기',
+'rcshowhidemine-hide' => '숨기기',
 'rclinks' => '최근 $2일간의 $1개 바뀐 문서 보기<br />$3',
 'diff' => '비교',
 'hist' => '역사',
@@ -2805,8 +2817,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => '이 IP 주소는 현재 차단되어 있습니다.
 차단 기록은 다음과 같습니다:',
 'sp-contributions-search' => '기여 검색',
+'sp-contributions-suppresslog' => '삭제된 사용자 기여',
 'sp-contributions-username' => 'IP 주소 또는 사용자 이름:',
 'sp-contributions-toponly' => '최신판만 보기',
+'sp-contributions-newonly' => '새 글인 기여만 보기',
 'sp-contributions-submit' => '검색',
 'sp-contributions-explain' => '',
 
index 6856c0f..9875b6b 100644 (file)
@@ -544,6 +544,7 @@ $2',
 'userlogin-resetpassword-link' => 'Паролну джибериу',
 'helplogin-url' => 'Help:Кириу',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Системагъа кириуде болушлукъ]]',
+'userlogin-createanother' => 'Башха аккаунт къурау',
 'createacct-join' => 'Билгилеринги тюбюрекде джаз.',
 'createacct-emailrequired' => 'Электрон почтаны адреси',
 'createacct-emailoptional' => 'Электрон почтаны адреси (амалсыз тюлдю)',
@@ -556,6 +557,7 @@ $2',
 'createacct-captcha' => 'Къоркъуусузлукъну тинтиу',
 'createacct-imgcaptcha-ph' => 'Башыракъда кёрюннген текстни джаз',
 'createacct-submit' => 'Тергеу джазыуну къура',
+'createacct-another-submit' => 'Энтда бир аккаунт къурау',
 'createacct-benefit-heading' => '{{SITENAME}} сизнича адамла бла къуралгъанды.',
 'createacct-benefit-body1' => '{{PLURAL:$1|тюрлениу}}',
 'createacct-benefit-body2' => '{{PLURAL:$1|бет}}',
@@ -620,6 +622,9 @@ $2',
 'login-abort-generic' => 'Системагъа кириу джетишимсиз болду',
 'loginlanguagelabel' => 'Тил: $1',
 'suspicious-userlogout' => 'Терс браузер неда кэш этиучу прокси берген соруугъа ушагъаны ючюн, Сизни чыгъаргъа сорууугъуз алынмагъанды.',
+'pt-login' => 'Кириу',
+'pt-createaccount' => 'Аккаунт къурау',
+'pt-userlogout' => 'Чыгъыу',
 
 # Email sending
 'php-mail-error-unknown' => "PHP's mail() функцияда белгили болмагъан халат",
index be47fce..44d0c5f 100644 (file)
@@ -674,7 +674,7 @@ Wann De wells, künnts De Ding [[Special:Preferences|Enschtällonge aanpaße]].'
 'userlogin-resetpassword-link' => 'Paßwoot verjäße?',
 'helplogin-url' => 'Help:Övver et Enlogge',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Hölp bem Enlogge]]',
-'userlogin-loggedin' => 'Do bes ald als {{GENDER:$1|dä Metmaacher|de Metmaacherėn|dä Metmaacher|de Metmaacherėn|däMetmaacher}} [[User:$1]] enjelogg. Met heh dämm Fommolaa kanns De jäz ävver onger enem andere Nahme enlogge.',
+'userlogin-loggedin' => 'Do bes ald als {{GENDER:$1|dä Metmaacher|de Metmaacherėn|dä Metmaacher|de Metmaacherėn|däMetmaacher}} [[User:$1|$1]] enjelogg. Met heh dämm Fommolaa kanns De jäz ävver onger enem andere Nahme enlogge.',
 'userlogin-createanother' => 'Donn ene zohsäzlejje Zohjang aanlääje',
 'createacct-join' => 'Jiv Ding Daate en:',
 'createacct-another-join' => 'Maach de nüüdeje Aanjaabe för dä neue Zohjaang.',
@@ -833,7 +833,7 @@ Do häs Der enzwesche e neu Zweschepaßwood jehollt.',
 'resetpass-temp-password' => 'Zweschepasswood:',
 'resetpass-abort-generic' => 'E Zohsazprojramm häd_et nit zohjelohße, et Paßwoot ze ändere.',
 'resetpass-expired' => 'Di Paßwood es afjeloufe. Donn jetz e neu Passwoot för et Enlogg faßlääje.',
-'resetpass-expired-soft' => 'Ding Paßwood es afjeloufe u moß neu jesaz wääde. Bes esu jood_un donn e neu Paßwoot ußsöhke, udder donn op {{int:cancel}} jonn, öm et schpääder ze säze.',
+'resetpass-expired-soft' => 'Ding Paßwood es afjeloufe un moß neu jesaz wääde. Bes esu jood_un donn e neu Paßwoot ußsöhke, udder jangk op {{int:resetpass-submit-cancel}}, öm et schpääder ze säze.',
 
 # Special:PasswordReset
 'passwordreset' => 'Et Paßwoot zeröck säze',
@@ -1748,11 +1748,23 @@ Do kann Der [[Special:ResetTokens|ene neue Schlößel maache lohße]], wann nü
 'rcnotefrom' => 'Hee {{PLURAL:$1|es ein|sin bes op <strong>$1</strong>|es keine}} fun de Änderunge zick dem <strong>$3</strong> öm <strong>$4</strong> Uhr opjelėß.',
 'rclistfrom' => 'Zeich de Änderunge vum $1 aan',
 'rcshowhideminor' => '$1 klein Mini-Änderunge',
+'rcshowhideminor-show' => 'Zeisch',
+'rcshowhideminor-hide' => 'Verschteihsch',
 'rcshowhidebots' => '$1 de Bots ehr Änderunge',
+'rcshowhidebots-show' => 'Zeisch',
+'rcshowhidebots-hide' => 'Verschteihsch',
 'rcshowhideliu' => 'De aanjemeldte Metmaacher ehr Änderunge: $1',
+'rcshowhideliu-show' => 'Zeisch',
+'rcshowhideliu-hide' => 'Verschteihsch',
 'rcshowhideanons' => '$1 de namenlose Metmaacher ehr Änderunge',
+'rcshowhideanons-show' => 'Zeisch',
+'rcshowhideanons-hide' => 'Verschteihsch',
 'rcshowhidepatr' => '$1 de nohjeluurte Änderunge',
+'rcshowhidepatr-show' => 'Zeisch',
+'rcshowhidepatr-hide' => 'Verschteihsch',
 'rcshowhidemine' => '$1 ming eije Änderunge',
+'rcshowhidemine-show' => 'Zeisch',
+'rcshowhidemine-hide' => 'Verschteihsch',
 'rclinks' => 'Zeich de letzte {{int:pipe-separator}}$1{{int:pipe-separator}} Änderunge us de letzte {{int:pipe-separator}}$2{{int:pipe-separator}} Däch, un dun {{int:pipe-separator}}$3',
 'diff' => 'Ungerscheid',
 'hist' => 'Versione',
@@ -1894,6 +1906,7 @@ wann De se noch han wells.',
 'php-uploaddisabledtext' => 'Et Dateie Huhlade es en PHP affjeschalldt.
 Bes esu joot un donn noh de Enshtellung <i lang="en">file_uploads</i> loore.',
 'uploadscripted' => 'En dä Datei es HTML dren oder Code vun enem Skripp, dä künnt Dinge Brauser en do verkihrte Hals krije un usführe.',
+'uploadscriptednamespace' => 'De aanjejovve <i lang="en" xml:lang="en">SVG</i>-Dattei benöds dä verbodde Nahme-Roum „$1“',
 'uploadinvalidxml' => 'Dat <i lang="en" xml:lang="en">XML</i> en dä huh jelaade Dattei kunnt wohr nit en Oodenong beim Ongersöhke.',
 'uploadvirus' => 'Esu ene Dress:
 <br />
@@ -2205,7 +2218,7 @@ All de Sigge em Wiki, och Klaafsigge, Ömleitunge, un esu jet',
 'statistics-views-peredit' => 'Sigge affjeroofe, pro Änderung',
 'statistics-users' => '[[Special:ListUsers|Metmaacher]] aajemelldt',
 'statistics-users-active' => 'Aktive Metmaacher',
-'statistics-users-active-desc' => 'Metmaacher, die {{PLURAL:$1|hück un jesterre|en de läzte $1 Dääsh|hück}} jät jemaat han.',
+'statistics-users-active-desc' => 'Aktiv sin Metmaacher, di {{PLURAL:$1|hück un jesterre|en de läzte $1 Dääsch|hück}} jät jemaat han.',
 'statistics-mostpopular' => 'De miets affjeroofe Sigge',
 
 'pageswithprop' => 'Sigge med en beschtemmpte Eijeschaff',
@@ -2770,8 +2783,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Heh di <i lang="en">IP</i>-Address es em Momang jesperrt.
 De neuste Sperr ier Enndraach em Logbooch es:',
 'sp-contributions-search' => 'Söök noh Metmaacher ier Beidräg',
+'sp-contributions-suppresslog' => 'verschtoche Beidrääch',
 'sp-contributions-username' => 'Metmaachername odder IP-Address:',
 'sp-contributions-toponly' => 'Bloß neuste Versione zeije',
+'sp-contributions-newonly' => 'Blohß neu aanjelaate Sigge zeije.',
 'sp-contributions-submit' => 'Söhke',
 
 # What links here
index c05d7db..9c4272f 100644 (file)
@@ -762,7 +762,7 @@ Vläicht hutt Dir Äert Passwuert scho geännert oder en neit temporäert Passwu
 'resetpass-temp-password' => 'Temporäert Passwuert:',
 'resetpass-abort-generic' => "D'Ännere vum Passwuert gouf duerch eng Erweiderung ofgebrach.",
 'resetpass-expired' => 'Äert Passwuert ass ofgelaf. Gitt w.e.g. en neit Passwuert u fir Iech anzeloggen.',
-'resetpass-expired-soft' => 'Äert Passwuert ass ofgelaf a muss zeréckgesat. Sicht w.e.g. elo en neit Passwuert eraus oder klickt ofbrieche fir et spéider zeréckzesetzen.',
+'resetpass-expired-soft' => 'Äert Passwuert ass ofgelaf a muss zeréckgesat. Sicht w.e.g. elo en neit Passwuert eraus oder klickt  "{{int:resetpass-submit-cancel}}" fir et spéider zeréckzesetzen.',
 
 # Special:PasswordReset
 'passwordreset' => 'Passwuert zrécksetzen',
index bf46880..845c41d 100644 (file)
@@ -146,12 +146,12 @@ $messages = array(
 'dec' => 'дек',
 
 # Categories related messages
-'pagecategories' => '{{PLURAL:$1|1=Категори|Категорияр}}',
+'pagecategories' => '{{PLURAL:$1|1=Категория|Категорияр}}',
 'category_header' => '«$1» категориядин ччинар',
 'subcategories' => 'агъакатегорияр',
 'category-media-header' => '"$1" категориядин медиа',
 'category-empty' => "''Алай чӀава и категория ичӀи я.\"",
-'hidden-categories' => '{{PLURAL:$1|1=Чуьнуьхай категори|Чуьнуьхай категорияр}}',
+'hidden-categories' => '{{PLURAL:$1|1=Чуьнуьхай категория|Чуьнуьхай категорияр}}',
 'hidden-category-category' => 'Чуьнуьхай категорияр',
 'category-subcat-count' => '{{PLURAL:$2|И категорияда анжах гуьгъуьна авай подкатегория ава.|$2-кай {{PLURAL:$1|1=агъакатегория|$1 агъакатегорияр}} къалурнава }}',
 'category-subcat-count-limited' => 'И категорияда {{PLURAL:$1|1=агъакатегория|$1 агъакатегорияр}} ава.',
@@ -866,7 +866,7 @@ $messages = array(
 'withoutinterwiki-submit' => 'Къалурун',
 
 # Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|баjт|баjтар}}',
+'nbytes' => '$1 {{PLURAL:$1|1=байт|байтар}}',
 'nmembers' => '$1 {{PLURAL:$1|1=уьзви|уьзвияр}}',
 'lonelypages' => 'Eтим xъувун',
 'prefixindex' => 'Префикс галай вири ччинар',
index e53b71b..549b006 100644 (file)
@@ -1527,9 +1527,17 @@ teisės",
 'rcnotefrom' => "Žemiau yra pakeitimai pradedant '''$2''' (rodoma iki '''$1''' pakeitimų).",
 'rclistfrom' => 'Rodyti naujus pakeitimus pradedant $1',
 'rcshowhideminor' => '$1 smulkius keitimus',
+'rcshowhideminor-show' => 'Rodyti',
+'rcshowhideminor-hide' => 'Slėpti',
 'rcshowhidebots' => '$1 robotus',
+'rcshowhidebots-show' => 'Rodyti',
+'rcshowhidebots-hide' => 'Slėpti',
 'rcshowhideliu' => '$1 prisijungusius naudotojus',
+'rcshowhideliu-show' => 'Rodyti',
+'rcshowhideliu-hide' => 'Slėpti',
 'rcshowhideanons' => '$1 anoniminius naudotojus',
+'rcshowhideanons-show' => 'Rodyti',
+'rcshowhideanons-hide' => 'Slėpti',
 'rcshowhidepatr' => '$1 patikrintus keitimus',
 'rcshowhidepatr-show' => 'Rodyti',
 'rcshowhidepatr-hide' => 'Slėpti',
@@ -1986,6 +1994,9 @@ Kiekvienoje eilutėje yra nuorodos į pirmąjį ir antrąjį peradresavimą, tai
 'protectedpages-indef' => 'Tik neapibrėžtos apsaugos',
 'protectedpages-cascade' => 'Tik pakopinė apsauga',
 'protectedpagesempty' => 'Šiuo metu nėra apsaugotas joks failas su šiais parametrais.',
+'protectedpages-page' => 'Puslapis',
+'protectedpages-expiry' => 'Galioja iki',
+'protectedpages-reason' => 'Priežastis',
 'protectedtitles' => 'Apsaugoti pavadinimai',
 'protectedtitlesempty' => 'Šiuo metu nėra jokių pavadinimų apsaugotų šiais parametrais.',
 'listusers' => 'Naudotojų sąrašas',
index 7e375bb..4d4e3b3 100644 (file)
@@ -746,7 +746,7 @@ $2',
 'customjsprotected' => 'Немате дозвола да ја менувате оваа страница со JavaScript  бидејќи содржи туѓи лични нагодувања.',
 'mycustomcssprotected' => 'Немате дозвола да ја уредувате оваа каскадна стилска страница (CSS).',
 'mycustomjsprotected' => 'Немате дозвола да ја уредувате оваа страница со JavaScript.',
-'myprivateinfoprotected' => 'Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ð° Ð´Ð° Ð³Ð¸ Ñ\83Ñ\80едÑ\83ваÑ\82е Ð²Ð°Ñ\88иÑ\82е Ð¿Ñ\80иваÑ\82ни информации.',
+'myprivateinfoprotected' => 'Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ð° Ð´Ð° Ð³Ð¸ Ñ\83Ñ\80едÑ\83ваÑ\82е Ð²Ð°Ñ\88иÑ\82е Ð»Ð¸Ñ\87ни информации.',
 'mypreferencesprotected' => 'Немате дозвола да ги уредувате вашите нагодувања.',
 'ns-specialprotected' => 'Специјални страници не може да се уредуваат.',
 'titleprotected' => "Овој наслов од страна на [[User:$1|$1]] е заштитен и не може да се создаде.
@@ -938,7 +938,7 @@ $2',
 'resetpass-temp-password' => 'Привремена лозинка:',
 'resetpass-abort-generic' => 'Смената на лозинката е откажана од додаток.',
 'resetpass-expired' => 'Лозинката ви е истечена. Задајте нова лозинка за да се најавите.',
-'resetpass-expired-soft' => 'Ð\9bозинкаÑ\82а Ð²Ð¸ Ðµ Ð¸Ñ\81Ñ\82еÑ\87ена Ð¸ Ñ\9cе Ð¼Ð¾Ñ\80а Ð´Ð° Ð·Ð°Ð´Ð°Ð´ÐµÑ\82е Ð½Ð¾Ð²Ð°. Ð\98збеÑ\80еÑ\82е Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ\81ега, Ð¸Ð»Ð¸ Ð¿Ð°Ðº Ð¾Ñ\82кажеÑ\82е Ð³Ð¾ за да ја зададете подоцна.',
+'resetpass-expired-soft' => 'Ð\9bозинкаÑ\82а Ð²Ð¸ Ðµ Ð¸Ñ\81Ñ\82еÑ\87ена Ð¸ Ñ\9cе Ð¼Ð¾Ñ\80а Ð´Ð° Ð·Ð°Ð´Ð°Ð´ÐµÑ\82е Ð½Ð¾Ð²Ð°. Ð\9eдбеÑ\80еÑ\82е Ð½Ð¾Ð²Ð° Ñ\81ега, Ð¸Ð»Ð¸ Ð¿Ð°Ðº Ñ\81Ñ\82иÑ\81неÑ\82е Ð½Ð° â\80\9e{{int:resetpass-submit-cancel}}â\80\9c за да ја зададете подоцна.',
 
 # Special:PasswordReset
 'passwordreset' => 'Менување на лозинка',
@@ -994,7 +994,7 @@ $2
 
 # Special:ResetTokens
 'resettokens' => 'Врати одново шифри',
-'resettokens-text' => 'Ð\9cожеÑ\82е Ñ\88иÑ\84Ñ\80иÑ\82е Ð´Ð° Ð³Ð¸ Ð²Ñ\80аÑ\82иÑ\82е Ð¾Ð´Ð½Ð¾Ð²Ð¾ Ñ\88Ñ\82о Ð¾Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ñ\83ва Ð¿Ñ\80иÑ\81Ñ\82ап Ð´Ð¾ Ð¸Ð·Ð²ÐµÑ\81ни Ð¿Ñ\80иваÑ\82ни податоци што се однесуваат на вашата овдешна сметка.
+'resettokens-text' => 'Ð\9cожеÑ\82е Ñ\88иÑ\84Ñ\80иÑ\82е Ð´Ð° Ð³Ð¸ Ð²Ñ\80аÑ\82иÑ\82е Ð¾Ð´Ð½Ð¾Ð²Ð¾ Ñ\88Ñ\82о Ð¾Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ñ\83ва Ð¿Ñ\80иÑ\81Ñ\82ап Ð´Ð¾ Ð¸Ð·Ð²ÐµÑ\81ни Ð»Ð¸Ñ\87ни податоци што се однесуваат на вашата овдешна сметка.
 
 Ова треба да се направи ако по грешка сте споделиле нешто со некого или ако сметката ви е изложена на опасност.',
 'resettokens-no-tokens' => 'Нема шифри за враќање.',
@@ -1697,7 +1697,7 @@ $1",
 'right-browsearchive' => 'Пребарување на избришани страници',
 'right-undelete' => 'Обновување избришана страница',
 'right-suppressrevision' => 'Прегледување и враќање на ревизии скриени од администратори',
-'right-suppressionlog' => 'Ð\93ледаÑ\9aе Ð½Ð° Ð¿Ñ\80иваÑ\82ни дневници',
+'right-suppressionlog' => 'Ð\93ледаÑ\9aе Ð½Ð° Ð»Ð¸Ñ\87ни дневници',
 'right-block' => 'Оневозможување на останати корисници да уредуваат',
 'right-blockemail' => 'Оневозможување корисници да праќаат е-пошта',
 'right-hideuser' => 'Блокирање корисници, сокривање од јавноста',
@@ -1715,8 +1715,8 @@ $1",
 'right-editmyuserjs' => 'Уредување на сопствени кориснички податотеки со JavaScript',
 'right-viewmywatchlist' => 'Преглед на вашиот список на набљудувања',
 'right-editmywatchlist' => 'Уредување на вашиот список на набљудувања. Извесни дејства сепак ќе ставаат страници во списокот и без да го имате ова право.',
-'right-viewmyprivateinfo' => 'Ð\9fÑ\80еглед Ð½Ð° Ñ\81опÑ\81Ñ\82вениÑ\82е Ð¿Ñ\80иваÑ\82ни податоци (на пр. е-пошта, вистинско име и презиме)',
-'right-editmyprivateinfo' => 'УÑ\80едÑ\83ваÑ\9aе Ð½Ð° Ñ\81опÑ\81Ñ\82вениÑ\82е Ð¿Ñ\80иваÑ\82ни податоци (на пр. е-пошта, вистинско име и презиме)',
+'right-viewmyprivateinfo' => 'Ð\9fÑ\80еглед Ð½Ð° Ñ\81опÑ\81Ñ\82вениÑ\82е Ð»Ð¸Ñ\87ни податоци (на пр. е-пошта, вистинско име и презиме)',
+'right-editmyprivateinfo' => 'УÑ\80едÑ\83ваÑ\9aе Ð½Ð° Ñ\81опÑ\81Ñ\82вениÑ\82е Ð»Ð¸Ñ\87ни податоци (на пр. е-пошта, вистинско име и презиме)',
 'right-editmyoptions' => 'Уредување на вашите нагодувања',
 'right-rollback' => 'Брзо отповикување на уредувањата на последниот корисник што уредувал одредена страница',
 'right-markbotedits' => 'Означување на вратени уредувања како ботовски уредувања',
@@ -1765,7 +1765,7 @@ $1",
 'action-browsearchive' => 'барање на избришани страници',
 'action-undelete' => 'обнови ја оваа страница',
 'action-suppressrevision' => 'прегледај ја и обнови ја оваа скриена ревизија',
-'action-suppressionlog' => 'преглед на овој приватен дневник',
+'action-suppressionlog' => 'преглед на овој li;en дневник',
 'action-block' => 'оневозможи го овој корисник да уредува',
 'action-protect' => 'измени го степенот на заштита на оваа страница',
 'action-rollback' => 'брзо отповикување на измени направени од последниот уредник на страницата',
@@ -1781,8 +1781,8 @@ $1",
 'action-sendemail' => 'испраќање на е-пошта',
 'action-editmywatchlist' => 'уредување на вашиот список на набљудувања',
 'action-viewmywatchlist' => 'преглед на вашиот список на набљудувања',
-'action-viewmyprivateinfo' => 'пÑ\80еглед Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð¿Ñ\80иваÑ\82ни податоци',
-'action-editmyprivateinfo' => 'Ñ\83Ñ\80едÑ\83ваÑ\9aе Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð¿Ñ\80иваÑ\82ни податоци',
+'action-viewmyprivateinfo' => 'пÑ\80еглед Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð»Ð¸Ñ\87ни податоци',
+'action-editmyprivateinfo' => 'Ñ\83Ñ\80едÑ\83ваÑ\9aе Ð½Ð° Ð²Ð°Ñ\88иÑ\82е Ð»Ð¸Ñ\87ни податоци',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|промена|промени}}',
@@ -1801,7 +1801,7 @@ $1",
 'recentchanges-legend-heading' => "'''Легенда:'''",
 'recentchanges-legend-newpage' => '(погл. и [[Special:NewPages|списокот на нови страници]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => 'Ð\9fодолÑ\83 Ñ\81е Ð¿Ñ\80омениÑ\82е Ð¾Ð´ <b>$2</b> (се прикажуваат до <b>$1</b>).',
+'rcnotefrom' => 'Ð\9fодолÑ\83 Ñ\81е Ð¿Ñ\80омениÑ\82е Ð½Ð°Ð¿Ñ\80авени Ð¾Ð´ <strong>$2</strong> Ð½Ð°Ð²Ð°Ð¼Ñ\83 (се прикажуваат до <b>$1</b>).',
 'rclistfrom' => 'Прикажи нови промени почнувајќи од $1',
 'rcshowhideminor' => '$1 ситни промени',
 'rcshowhideminor-show' => 'Прикажи',
@@ -2080,7 +2080,7 @@ $1',
 'img-auth-isdir' => 'Се обидувате да пристапите до именикот „$1“.
 Допуштен е само податотечен пристап.',
 'img-auth-streaming' => 'Емитување „$1“.',
-'img-auth-public' => 'ФÑ\83нкÑ\86иÑ\98аÑ\82а Ð½Ð° img_auth.php Ñ\81лÑ\83жи Ð·Ð° Ð¸Ð·Ð»ÐµÐ· Ð½Ð° Ð¿Ð¾Ð´Ð°Ñ\82оÑ\82еки Ð¾Ð´ Ð¿Ñ\80иваÑ\82ни викија.
+'img-auth-public' => 'ФÑ\83нкÑ\86иÑ\98аÑ\82а Ð½Ð° img_auth.php Ñ\81лÑ\83жи Ð·Ð° Ð¸Ð·Ð»ÐµÐ· Ð½Ð° Ð¿Ð¾Ð´Ð°Ñ\82оÑ\82еки Ð¾Ð´ Ð»Ð¸Ñ\87ни викија.
 Ова вики е нагодено како јавно вики.
 Од причини на оптимална сигурност, img_auth.php е оневозможен.',
 'img-auth-noread' => 'Корисникот нема пристап за читање на „$1“.',
@@ -2804,6 +2804,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Оваа IP-адреса е моментално блокирана.
 Подолу е наведен најновиот дневнички запис на блокирање:',
 'sp-contributions-search' => 'Пребарување на придонеси',
+'sp-contributions-suppresslog' => 'притаени придонеси на корисникот',
 'sp-contributions-username' => 'IP-адреса или корисничко име:',
 'sp-contributions-toponly' => 'Прикажувај само последни ревизии',
 'sp-contributions-newonly' => 'Прикажувај само новосоздадени страници',
@@ -2944,7 +2945,7 @@ $1',
 'ip_range_toolarge' => 'Не се дозволени опсежни блокирања поголеми од /$1.',
 'proxyblocker' => 'Блокер на застапници (proxy)',
 'proxyblockreason' => 'Вашата IP-адреса е блокирана бидејќи претставува отворен застапник (proxy).
-Ве молиме контактирајте со вашиот доставувач на Интернет услуги или техничката поддршка и информирајте ги за овој сериозен безбедносен проблем.',
+Ве молиме контактирајте со вашиот семрежен услужник и или техничката поддршка и информирајте ги за овој сериозен безбедносен проблем.',
 'sorbs' => 'DNSBL',
 'sorbsreason' => 'Вашата IP-адреса е запишана како отворен застапник (proxy) во DNSBL кој го користи {{SITENAME}}..',
 'sorbs_create_account_reason' => 'Вашата IP-адреса е наведена како отворен застапникот (proxy) во DNSBL користена од {{SITENAME}}.
index bc335b8..b5ede05 100644 (file)
@@ -209,7 +209,7 @@ $messages = array(
 'vector-action-unprotect' => 'Хамгаалалтаа солих',
 'vector-view-create' => 'Үүсгэх',
 'vector-view-edit' => 'Засварлах',
-'vector-view-history' => 'Түүх',
+'vector-view-history' => 'Ð\97аÑ\81ваÑ\80Ñ\8bн Ñ\82үүх',
 'vector-view-view' => 'Унших',
 'vector-view-viewsource' => 'Кодыг харах',
 'actions' => 'Үйлдлүүд',
@@ -326,8 +326,8 @@ $1',
 'toc' => 'Агуулга',
 'showtoc' => 'дэлгэх',
 'hidetoc' => 'хумих',
-'collapsible-collapse' => 'Хумих',
-'collapsible-expand' => 'Ð\94элгэх',
+'collapsible-collapse' => 'хумих',
+'collapsible-expand' => 'дэлгэх',
 'thisisdeleted' => '$1-г харах эсвэл сэргээх үү?',
 'viewdeleted' => '$1-г харах уу?',
 'restorelink' => '{{PLURAL:$1|арилгасан засвар|арилгасан $1 засварууд}}',
@@ -562,6 +562,9 @@ $2',
 'login-abort-generic' => 'Та нэвтэрч чадсангүй',
 'loginlanguagelabel' => 'Хэл: $1',
 'suspicious-userlogout' => 'Таны гарах хүсэлт нь эвдэрхий хөтөч буюу кэшлэгч проксигоор явуулсан мэт харагдаж байгаа тул зөвшөөрсөнгүй.',
+'pt-login' => 'Нэвтрэх',
+'pt-createaccount' => 'Бүртгүүлэх',
+'pt-userlogout' => 'Гарах',
 
 # Email sending
 'php-mail-error-unknown' => "PHP's mail() функцэд үл танигдах алдаа гарлаа.",
@@ -585,6 +588,7 @@ $2',
 'resetpass-wrong-oldpass' => 'Хүчингүй түр зуурын эсвэл одоогийн нууц үг байна.
 Та аль хэдийнээ нууц үгээ сольсон эсвэл түр зуурын нууц үг хүссэн байна.',
 'resetpass-temp-password' => 'Түр зуурын нууц үг:',
+'resetpass-expired' => 'Нууц үгийн хугацаа дууссан байна. Шинэ нууц үг оруулж нэвтрэнэ үү.',
 
 # Special:PasswordReset
 'passwordreset' => 'Нууц үгийг сэргээх',
@@ -883,7 +887,7 @@ $3-н тодорхойлсон шалтгаан нь ''$2''",
 'page_last' => 'сүүлийн',
 'histlegend' => 'Радио товчлууруудыг сонгож дарсаны дараа enter товчлуурыг, эсвэл хуудасны доод талд байгаа товчлуур дээр дарж засваруудыг хооронд нь харьцуулна уу.<br />
 
-Тайлбар: strong>({{int:cur}})</strong> = хамгийн шинэ хувилбартай харьцуулалт, <strong>({{int:last}})</strong> = өмнөх хувилбартайх харьцуулалт, <strong>{{int:minoreditletter}}</strong> = бага хэмжээний засвар',
+Тайлбар: <strong>({{int:cur}})</strong> = одоогийн хувилбартай харьцуулах, <strong>({{int:last}})</strong> = өмнөх хувилбартай нь харьцуулах, <strong>{{int:minoreditletter}}</strong> = бага хэмжээний засвар',
 'history-fieldset-title' => 'Түүх сөхье',
 'history-show-deleted' => 'Зөвхөн устгагдсаныг',
 'histfirst' => 'хамгийн эхэнд',
@@ -1355,20 +1359,23 @@ $1 тэмдэгтээс богино байх ёстой.',
 # Recent changes
 'nchanges' => '$1 өөрчлөлт',
 'recentchanges' => 'Сүүлийн өөрчлөлтүүд',
-'recentchanges-legend' => 'Сүүлийн өөрчлөлтүүдийн сонголтууд',
+'recentchanges-legend' => 'Сар өдөр, шинж төрлөөр шүүх хүснэгт',
 'recentchanges-summary' => 'Энэхүү хуудсанд викид хийсэн хамгийн сүүлийн өөрчлөлтүүдийг үзүүлж байна.',
 'recentchanges-feed-description' => 'Вики дахь хамгийн сүүлийн өөрчлөлтүүдийг хянах.',
-'recentchanges-label-newpage' => 'ЭнÑ\8d Ð·Ð°Ñ\81ваÑ\80 Ñ\88инÑ\8d Ñ\85Ñ\83Ñ\83дÑ\81Ñ\8bг Ò¯Ò¯Ñ\81гÑ\8dсэн байна',
-'recentchanges-label-minor' => 'ЭнÑ\8d Ð½Ñ\8c Ð±Ð°Ð³Ð° Ð·Ñ\8dÑ\80гийн Ð·Ð°Ñ\81ваÑ\80 Ð±Ð°Ð¹Ð½Ð°',
-'recentchanges-label-bot' => 'ЭнÑ\8d Ð·Ð°Ñ\81ваÑ\80Ñ\8bг Ñ\80обоÑ\82 Ð³Ò¯Ð¹Ñ\86Ñ\8dÑ\82гÑ\8dÑ\81Ñ\8dн Ð±Ð°Ð¹Ð½Ð°',
+'recentchanges-label-newpage' => 'ШинÑ\8d Ñ\85Ñ\83Ñ\83даÑ\81 Ò¯Ò¯Ñ\81сэн байна',
+'recentchanges-label-minor' => 'Ð\91ага Ð·Ñ\8dÑ\80гийн Ð·Ð°Ñ\81ваÑ\80',
+'recentchanges-label-bot' => 'РобоÑ\82 Ð³Ò¯Ð¹Ñ\86Ñ\8dÑ\82гÑ\8dÑ\81Ñ\8dн Ð·Ð°Ñ\81ваÑ\80',
 'recentchanges-label-unpatrolled' => 'Энэ засварыг одоогийн байдлаар манаагүй байна',
-'recentchanges-legend-newpage' => '([[Special:NewPages|тэдгээрийг жагсааж үзэх]]',
+'recentchanges-label-plusminus' => 'Өөрчлөгдсөн байт хэмжээ',
+'recentchanges-legend-newpage' => '([[Special:NewPages|жагсааж харах]])',
 'rcnotefrom' => "Доорх нь '''$2'''-с хойших өөрчлөлтүүд ('''$1''' хүртэлхийг харуулав) юм.",
 'rclistfrom' => '$1-с хойших шинэ засваруудыг үзүүлэх',
 'rcshowhideminor' => 'Бага зэргийн засваруудыг $1',
 'rcshowhidebots' => 'Роботуудыг $1',
 'rcshowhideliu' => 'Нийт $1 бүртгэгдсэн хэрэглэгчид',
 'rcshowhideanons' => 'Бүртгэлгүй хэрэглэгчдийг $1',
+'rcshowhideanons-show' => 'үзүүлэх',
+'rcshowhideanons-hide' => 'нуух',
 'rcshowhidepatr' => 'Хянагдаж буй засваруудыг $1',
 'rcshowhidemine' => 'Миний засваруудыг $1',
 'rclinks' => 'Сүүлийн $2 өдрийн турших $1 засварыг үзүүлэх<br />$3',
@@ -1908,7 +1915,7 @@ URL нь зөв болон сайт ажиллагаатай байгаа эсэ
 # Special:LinkSearch
 'linksearch' => 'Гадаад холбоос хайлт',
 'linksearch-pat' => 'Хэв маягийг хайх:',
-'linksearch-ns' => 'Ð\9dÑ\8dÑ\80ний Ð·Ð°Ð¹:',
+'linksearch-ns' => 'Ð¥Ñ\83Ñ\83дÑ\81Ñ\8bн Ñ\82Ó©Ñ\80өл:',
 'linksearch-ok' => 'Хайх',
 'linksearch-text' => '"*.wikipedia.org" зэрэг орлуулагч тэмдэгт хэрэглэх боломжтой.<br />
 Дор хаяж дээд түвшиний домайн хэрэгтэй байна, жишээ нь "*.org".<br />
index 3f5268e..d580427 100644 (file)
@@ -7,6 +7,7 @@
  * @ingroup Language
  * @file
  *
+ * @author C.R.
  * @author Carmine Colacino
  * @author Chelin
  * @author Cryptex
@@ -281,7 +282,7 @@ $messages = array(
 'feedlinks' => 'Feed:',
 'site-atom-feed' => "Feed Atom 'e $1",
 'page-atom-feed' => 'Feed Atom ppe "$1"',
-'red-link-title' => '$1 (a paggena nun esiste)',
+'red-link-title' => "$1 ('a paggena nun esiste)",
 
 # Short words for each namespace, by default used in the namespace tab in monobook
 'nstab-main' => 'Articulo',
@@ -637,6 +638,7 @@ Vere anche 'e [[Special:WantedCategories|categurìe richieste]].",
 'sp-contributions-blocklog' => 'blocche',
 'sp-contributions-logs' => 'registre',
 'sp-contributions-talk' => 'Chiàcchiera',
+'sp-contributions-suppresslog' => 'contribbute utente scancellate',
 'sp-contributions-username' => 'Nnerizzo IP o nomme utente',
 'sp-contributions-submit' => 'Truova',
 
@@ -718,7 +720,7 @@ Vere anche 'e [[Special:WantedCategories|categurìe richieste]].",
 'tooltip-p-logo' => 'Visita a paggena prencepale',
 'tooltip-n-mainpage' => 'Visita a paggena prencepale',
 'tooltip-n-mainpage-description' => 'Visita a paggena prencepale',
-'tooltip-n-portal' => 'Descrizione ddo prugietto, che pou fa, addo truova e cose',
+'tooltip-n-portal' => "Descrizione d&#39;'o prugietto, che po' ffa, addò truvà 'e ccose",
 'tooltip-n-recentchanges' => 'Ennece dde urdeme cagnamiénte ddo sito',
 'tooltip-n-randompage' => 'Na paggena qualsiase',
 'tooltip-n-help' => "Paggena 'e ajùto",
index c5a3341..5a45e9e 100644 (file)
@@ -1739,7 +1739,7 @@ Informasjonen vil være offentlig.',
 'recentchanges-legend-heading' => "'''Tegnforklaring:'''",
 'recentchanges-legend-newpage' => '(se også [[Special:NewPages|liste av nye sider]])',
 'recentchanges-legend-plusminus' => '«(±123)»',
-'rcnotefrom' => "Nedenfor er endringene siden '''$2''' (opp til '''$1''' vises).",
+'rcnotefrom' => 'Nedenfor er endringene gjort siden <strong>$2</strong> (frem til <strong>$1</strong> vises).',
 'rclistfrom' => 'Vis nye endringer med start fra $1',
 'rcshowhideminor' => '$1 mindre endringer',
 'rcshowhidebots' => '$1 roboter',
index d1604ba..c7f6d9e 100644 (file)
@@ -971,7 +971,7 @@ Om het inloggen te voltooien moet u hier een nieuw wachtwoord instellen:',
 'resetpass-temp-password' => 'Tijdelijk wachtwoord:',
 'resetpass-abort-generic' => 'De wachtwoordwijziging is afgebroken door een uitbreiding.',
 'resetpass-expired' => 'Uw wachtwoord is verlopen. Stel een nieuw wachtwoord om in te loggen.',
-'resetpass-expired-soft' => 'Uw wachtwoord is verlopen, en moet opnieuw worden ingesteld. Kies een nieuw wachtwoord nu, of klik op Annuleren als u het later opnieuw wilt.',
+'resetpass-expired-soft' => 'Uw wachtwoord is verlopen, en moet opnieuw worden ingesteld. Kies een nieuw wachtwoord nu, of klik op "{{int:resetpass-submit-cancel}}" als u het later opnieuw wilt.',
 
 # Special:PasswordReset
 'passwordreset' => 'Wachtwoord opnieuw instellen',
index 0371b7b..8f42463 100644 (file)
@@ -2388,6 +2388,7 @@ Attendemelding og hjelp:
 'delete-edit-reasonlist' => 'Endre grunnar til sletting',
 'delete-toobig' => 'Denne sida har ein stor endringsshistorikk, med over {{PLURAL:$1|$1&nbsp;endring|$1&nbsp;endringar}}. Sletting av slike sider er avgrensa for å unngå utilsikta forstyrring av {{SITENAME}}.',
 'delete-warning-toobig' => 'Denne sida har ein lang endringshistorikk, med meir enn {{PLURAL:$1|$1&nbsp;endring|$1&nbsp;endringar}}. Dersom du slettar henne kan det forstyrre handlingar i databasen til {{SITENAME}}, ver varsam.',
+'deleting-backlinks-warning' => "'''Åtvaring''': Andre sider lenkjer til eller inkluderer sida du er i ferd med å sletta.",
 
 # Rollback
 'rollback' => 'Rull attende endringar',
index 5972860..1c472ef 100644 (file)
@@ -897,7 +897,7 @@ Aby dokończyć logowanie, musisz ustawić nowe hasło tutaj:',
 'resetpass-temp-password' => 'Tymczasowe hasło:',
 'resetpass-abort-generic' => 'Zmiana hasła została przerwana przez rozszerzenie.',
 'resetpass-expired' => 'Twoje hasło wygasło. Proszę ustawić nowe hasło do logowania.',
-'resetpass-expired-soft' => 'Twoje hasło wygasło i musi zostać zresetowane. Proszę wybrać nowe hasło albo kliknąć przycisk Anuluj, aby zresetować je później.',
+'resetpass-expired-soft' => 'Twoje hasło wygasło i musi zostać zresetowane. Proszę wybrać nowe hasło albo kliknąć na "{{int:resetpass-submit-cancel}}", aby zresetować je później.',
 
 # Special:PasswordReset
 'passwordreset' => 'Wyczyść hasło',
@@ -1062,11 +1062,11 @@ Upewnij się, czy na pewno zamierza{{GENDER:|łeś|łaś|sz}} utworzyć lub zmod
 'userpage-userdoesnotexist-view' => 'Konto użytkownika „$1” nie jest zarejestrowane.',
 'blocked-notice-logextract' => '{{GENDER:$1|Ten użytkownik|Ta użytkowniczka}} jest obecnie {{GENDER:$1|zablokowany|zablokowana}}.
 Ostatni wpis rejestru blokad jest pokazany poniżej.',
-'clearyourcache' => "'''Uwaga:''' aby zobaczyć zmiany po zapisaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.
-* '''Firefox / Safari:''' Przytrzymaj ''Shift'' podczas klikania ''Odśwież bieżącą stronę'', lub naciśnij klawisze ''Ctrl+F5'' lub ''Ctrl+R'' (''⌘-R'' na komputerze Mac)
-* '''Google Chrome:''' Naciśnij ''Ctrl-Shift-R'' (''⌘-Shift-R'' na komputerze Mac)
-* '''Internet Explorer:''' Przytrzymaj ''Ctrl'' jednocześnie klikając ''Odśwież'' lub naciśnij klawisze ''Ctrl+F5''
-* '''Opera:''' Wyczyść pamięć podręczną w ''Narzędzia → Preferencje''",
+'clearyourcache' => '<strong>Uwaga:</strong> aby zobaczyć zmiany po zapisaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.
+* <strong>Firefox / Safari:</strong> Przytrzymaj <em>Shift</em> podczas klikania <em>Odśwież bieżącą stronę</em>, lub naciśnij klawisze <em>Ctrl+F5</em> lub <em>Ctrl+R</em> (<em>⌘-R</em> na komputerze Mac)
+* <strong>Google Chrome:</strong> Naciśnij <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na komputerze Mac)
+* <strong>Internet Explorer:</strong> Przytrzymaj <em>Ctrl</em>, jednocześnie klikając <em>Odśwież</em>, lub naciśnij klawisze <em>Ctrl+F5</em>
+* <strong>Opera:</strong> Wyczyść pamięć podręczną w <em>Narzędzia → Preferencje</em>',
 'usercssyoucanpreview' => "'''Podpowiedź:''' Użyj przycisku „Podgląd”, aby przetestować nowy arkusz stylów CSS przed jego zapisaniem.",
 'userjsyoucanpreview' => "'''Podpowiedź:''' Użyj przycisku „Podgląd”, aby przetestować nowy kod JavaScript przed jego zapisaniem.",
 'usercsspreview' => "'''Pamiętaj, że to tylko podgląd arkusza stylów CSS – nic jeszcze nie zostało zapisane!'''",
@@ -2382,7 +2382,7 @@ Wymaga podania co najmniej domeny najwyższego poziomu np. „*.org”.<br />
 # Special:ActiveUsers
 'activeusers' => 'Lista aktywnych użytkowników',
 'activeusers-intro' => 'Poniżej znajduje się lista użytkowników, którzy byli aktywni w ciągu {{PLURAL:$1|ostatniego dnia|ostatnich $1 dni}}.',
-'activeusers-count' => 'w ciągu {{PLURAL:$3|ostatniego dnia|ostatnich $3 dni}} {{GENDER:$2|wykonał|wykonała|wykonał}} $1 {{PLURAL:$1|edycję|edycje|edycji}}',
+'activeusers-count' => 'w ciągu {{PLURAL:$3|ostatniego dnia|ostatnich $3 dni}} {{GENDER:$2|wykonał|wykonała|wykonał}} $1 {{PLURAL:$1|operację|operacje|operacji}}',
 'activeusers-from' => 'Pokaż użytkowników zaczynając od',
 'activeusers-hidebots' => 'Ukryj boty',
 'activeusers-hidesysops' => 'Ukryj administratorów',
index 6096568..3e0ce1b 100644 (file)
@@ -615,7 +615,7 @@ Për finì ëd rintré ant ël sistema, a dev definì na neuva ciav ambelessì:"
 'resetpass-temp-password' => 'Ciav provisòria:',
 'resetpass-abort-generic' => "La modìfica ëd la ciav a l'é stàita anulà da n'estension.",
 'resetpass-expired' => "Soa ciav a l'é scadùa. Për piasì, ch'a definissa na ciav neuva për rintré ant ël sistema.",
-'resetpass-expired-soft' => "Soa ciav a l'é scadùa e a l'ha damanca d'esse arnovà. Për piasì, ch'a serna na neuva ciav adess o ch'a sgnaca su anulé për cangela pi tard.",
+'resetpass-expired-soft' => "Soa ciav a l'é scadùa e a l'ha damanca d'esse arnovà. Për piasì, ch'a serna na neuva ciav adess o ch'a sgnaca su «{{int:resetpass-submit-cancel}}» për cangela pi tard.",
 
 # Special:PasswordReset
 'passwordreset' => 'Ri-inissialisassion ëd la ciav',
@@ -1464,7 +1464,7 @@ Costa anformassion a sarà pùblica.",
 'recentchanges-legend-heading' => "'''Legend:'''",
 'recentchanges-legend-newpage' => '(vëdde ëdcò [[Special:NewPages|lista dle pàgine neuve]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => ' Ambelessì sota a-i é la lista dle modìfiche da <b>$2</b> (fin-a a <b>$1</b>).',
+'rcnotefrom' => 'Ambelessì sota a-i é la lista dle modìfiche da <strong>$2</strong> (mostrà fin-a a <strong>$1</strong>).',
 'rclistfrom' => 'Mostré le modìfiche a parte da $1',
 'rcshowhideminor' => '$1 le modìfiche cite',
 'rcshowhideminor-show' => 'Smon-e',
@@ -1613,7 +1613,7 @@ A dovrìa ciamé a cheidun con la possibilità ëd vëdde ij dàit dj'archivi el
 'php-uploaddisabledtext' => "Ij cariament d'archivi a son disabilità an PHP.
 Për piasì, ch'a controla l'ampostassion file_uploads.",
 'uploadscripted' => "St'archivi-sì a l'ha andrinta chèich-còs (dël còdes HTML ò pura un senari) che a podrìa esse travajà mal da chèich programa ëd navigassion.",
-'uploadscriptednamespace' => "S'archivi SVG a conten në spassi nominal «1» nen autorisà",
+'uploadscriptednamespace' => "S'archivi SVG a conten në spassi nominal «$1» nen autorisà",
 'uploadinvalidxml' => "L'XML ant l'archivi carià a l'ha nen podù esse analisà.",
 'uploadvirus' => "St'archivi-sì a l'han andrinta un '''vìrus!''' Detaj: $1",
 'uploadjava' => "L'archivi a l'é n'archivi ZIP ch'a conten n'archivi Java .class.
index 8c69d22..f049a13 100644 (file)
@@ -324,7 +324,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Sublinhar ligação:',
+'tog-underline' => 'Sublinhar links:',
 'tog-hideminor' => 'Esconder edições menores nas mudanças recentes',
 'tog-hidepatrolled' => 'Esconder edições patrulhadas nas mudanças recentes',
 'tog-newpageshidepatrolled' => 'Esconder páginas patrulhadas na lista de páginas novas',
@@ -333,7 +333,7 @@ $messages = array(
 'tog-numberheadings' => 'Auto-numerar cabeçalhos',
 'tog-showtoolbar' => 'Mostrar barra de edição',
 'tog-editondblclick' => 'Editar páginas quando houver um clique duplo',
-'tog-editsectiononrightclick' => 'Possibilitar a edição de seções por clique com o botão direito no título da seção',
+'tog-editsectiononrightclick' => 'Possibilitar a edição de secções por clique com o botão direito no título da secção',
 'tog-rememberpassword' => 'Recordar os meus dados neste browser (no máximo, durante $1 {{PLURAL:$1|dia|dias}})',
 'tog-watchcreations' => 'Adicionar as páginas e ficheiros que eu criar às minhas páginas vigiadas',
 'tog-watchdefault' => 'Adicionar as páginas e ficheiros que eu editar às minhas páginas vigiadas',
@@ -363,7 +363,7 @@ $messages = array(
 'tog-noconvertlink' => 'Impossibilitar a conversão dos títulos de links',
 'tog-norollbackdiff' => 'Omitir diferenças depois de reverter edições em bloco',
 'tog-useeditwarning' => 'Avisar-me ao abandonar uma página editada sem gravar as alterações.',
-'tog-prefershttps' => 'Sempre utilizar uma conexão segura ao iniciar sessão',
+'tog-prefershttps' => 'Usar sempre uma ligação segura quando estiver autenticado',
 
 'underline-always' => 'Sempre',
 'underline-never' => 'Nunca',
@@ -373,7 +373,7 @@ $messages = array(
 'editfont-style' => 'Fonte de edição:',
 'editfont-default' => 'Fonte por omissão, do browser',
 'editfont-monospace' => 'Fonte monoespaçada',
-'editfont-sansserif' => 'Fonte sans-serif',
+'editfont-sansserif' => 'Fonte sem serifa',
 'editfont-serif' => 'Fonte serifada',
 
 # Dates
@@ -573,7 +573,7 @@ $1',
 'disclaimerpage' => 'Project:Aviso_geral',
 'edithelp' => 'Ajuda de edição',
 'helppage' => 'Help:Conteúdos',
-'mainpage' => 'Página principal',
+'mainpage' => 'Página Principal',
 'mainpage-description' => 'Página principal',
 'policy-url' => 'Project:Políticas',
 'portal' => 'Portal comunitário',
@@ -591,8 +591,8 @@ Consulte a página da [[Special:Version|versão do sistema]].',
 
 'ok' => 'OK',
 'retrievedfrom' => 'Obtida de "$1"',
-'youhavenewmessages' => 'Tem $1 ($2).',
-'youhavenewmessagesfromusers' => 'Tem $1 de {{PLURAL:$3|outro utilizador|$3 utilizadores}} ($2).',
+'youhavenewmessages' => '{{PLURAL:$3|Tem}} $1 ($2).',
+'youhavenewmessagesfromusers' => '{{PLURAL:$4|Tem}} $1 de {{PLURAL:$3|outro utilizador|$3 utilizadores}} ($2).',
 'youhavenewmessagesmanyusers' => 'Tem $1 de muitos utilizadores ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|uma mensagem nova|999=mensagens novas}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|última alteração|999=últimas alterações}}',
@@ -900,7 +900,7 @@ Para completar a autenticação, tem de definir uma palavra-chave nova aqui:',
 'resetpass-temp-password' => 'Palavra-chave temporária:',
 'resetpass-abort-generic' => 'A alteração da palavra-chave foi cancelada por uma extensão.',
 'resetpass-expired' => 'A sua palavra-chave expirou. Para autenticar-se, defina uma nova.',
-'resetpass-expired-soft' => 'A sua palavra-chave expirou e tem de ser redefinida. Escolha uma nova agora ou clique cancelar para redefini-la mais tarde.',
+'resetpass-expired-soft' => 'A sua palavra-chave expirou e tem de ser redefinida. Escolha uma nova agora ou clique "{{int:resetpass-submit-cancel}}" para redefini-la mais tarde.',
 
 # Special:PasswordReset
 'passwordreset' => 'Redefinir palavra-chave',
@@ -1264,31 +1264,31 @@ Tente [[Special:Search|pesquisar na wiki]] novas páginas relevantes.',
 'rev-deleted-user' => '(nome de utilizador removido)',
 'rev-deleted-event' => '(entrada removida)',
 'rev-deleted-user-contribs' => '[nome de utilizador ou IP removido - edição ocultada das contribuições]',
-'rev-deleted-text-permission' => "Esta revisão de página foi '''eliminada'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
-'rev-deleted-text-unhide' => "Esta revisão de página foi '''eliminada'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].
-Pode mesmo assim [$1 ver esta edição] se deseja prosseguir.",
-'rev-suppressed-text-unhide' => "Esta revisão de página foi '''suprimida'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].
-Pode mesmo assim [$1 ver esta revisão] se deseja prosseguir.",
-'rev-deleted-text-view' => "Esta revisão de página foi '''eliminada'''.
-Você pode vê-la; podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
-'rev-suppressed-text-view' => "Esta revisão de página foi '''suprimida'''.
-Você pode vê-la; podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].",
-'rev-deleted-no-diff' => "Não pode ver esta diferença entre revisões porque uma das revisões foi '''eliminada'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
-'rev-suppressed-no-diff' => "Não pode ver esta diferença entre versões porque uma das revisões foi '''eliminada'''.",
-'rev-deleted-unhide-diff' => "Uma das revisões desta diferença entre revisões foi '''eliminada'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].
-Pode mesmo assim [$1 ver estas diferenças] se deseja prosseguir.",
-'rev-suppressed-unhide-diff' => "Uma das revisões desta diferença entre revisões foi '''suprimida'''.
-Podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].
-Pode mesmo assim [$1 ver estas diferenças] se deseja prosseguir.",
-'rev-deleted-diff-view' => "Uma das revisões desta diferença entre revisões foi '''eliminada'''.
-Você pode ver a diferença entre revisões; podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
-'rev-suppressed-diff-view' => "Uma das revisões desta diferença entre revisões foi '''suprimida'''.
-Você pode ver a diferença entre revisões; podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].",
+'rev-deleted-text-permission' => 'Esta revisão de página foi <strong>eliminada</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].',
+'rev-deleted-text-unhide' => 'Esta revisão de página foi <strong>eliminada</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].
+Pode mesmo assim [$1 ver esta revisão] se deseja prosseguir.',
+'rev-suppressed-text-unhide' => 'Esta revisão de página foi <strong>suprimida</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].
+Pode mesmo assim [$1 ver esta revisão] se deseja prosseguir.',
+'rev-deleted-text-view' => 'Esta revisão de página foi <strong>eliminada</strong>.
+Você pode vê-la; encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].',
+'rev-suppressed-text-view' => 'Esta revisão de página foi <strong>suprimida</strong>.
+Você pode vê-la; encontrará detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].',
+'rev-deleted-no-diff' => 'Não pode ver esta diferença entre revisões porque uma das revisões foi <strong>eliminada</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].',
+'rev-suppressed-no-diff' => 'Não pode ver esta diferença entre versões porque uma das revisões foi <strong>eliminada</strong>.',
+'rev-deleted-unhide-diff' => 'Uma das revisões desta diferença entre revisões foi <strong>eliminada</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].
+Pode mesmo assim [$1 ver estas diferenças] se deseja prosseguir.',
+'rev-suppressed-unhide-diff' => 'Uma das revisões desta diferença entre revisões foi <strong>suprimida</strong>.
+Encontrará detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].
+Pode mesmo assim [$1 ver estas diferenças] se deseja prosseguir.',
+'rev-deleted-diff-view' => 'Uma das revisões desta diferença entre revisões foi <strong>eliminada</strong>.
+Pode ver a diferença entre revisões; encontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].',
+'rev-suppressed-diff-view' => 'Uma das revisões desta diferença entre revisões foi <strong>suprimida</strong>.
+Pode ver a diferença entre revisões; encontrará detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].',
 'rev-delundel' => 'mostrar/esconder',
 'rev-showdeleted' => 'mostrar',
 'revisiondelete' => 'Eliminar/restaurar edições',
@@ -1299,8 +1299,8 @@ Você pode ver a diferença entre revisões; podem existir mais detalhes no [{{f
 'revdelete-show-file-submit' => 'Sim',
 'revdelete-selected' => "'''{{PLURAL:$2|Edição selecionada|Edições selecionadas}} de [[:$1]]:'''",
 'logdelete-selected' => "'''{{PLURAL:$1|Evento do registo selecionado|Eventos do registo selecionados}}:'''",
-'revdelete-text' => "'''Edições e eventos eliminados continuarão a aparecer no histórico e registos da página, mas partes do seu conteúdo estarão inacessíveis ao público.'''
-Outros administradores da {{SITENAME}} continuarão a poder aceder ao conteúdo escondido e podem restaurá-lo novamente através desta mesma interface, a menos que restrições adicionais sejam definidas.",
+'revdelete-text' => '<strong>Edições e operações eliminadas continuarão a aparecer no histórico da página e nos registos, mas partes do seu conteúdo estarão inacessíveis ao público.</strong>
+Outros administradores da {{SITENAME}} continuarão a poder aceder ao conteúdo escondido e podem repô-lo através desta mesma interface, a menos que restrições adicionais sejam definidas.',
 'revdelete-confirm' => 'Por favor confirme que pretende executar esta operação, que compreende as suas consequências e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].',
 'revdelete-suppress-text' => "A supressão '''só''' deverá ser usada nos seguintes casos:
 * Informação potencialmente caluniosa, difamatória ou injuriosa
@@ -1417,7 +1417,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'nextn-title' => '{{PLURAL:$1|próximo|próximos}} $1 {{PLURAL:$1|resultado|resultados}}',
 'shown-title' => 'Mostrar $1 {{PLURAL:$1|resultado|resultados}} por página',
 'viewprevnext' => 'Ver ($1 {{int:pipe-separator}} $2) ($3).',
-'searchmenu-exists' => "'''Há uma página com o nome \"[[:\$1]]\" nesta wiki'''",
+'searchmenu-exists' => '<strong>Há uma página com o nome "[[:$1]]" nesta wiki.</strong> {{PLURAL:$2|0=|Veja também os outros resultados encontrados.}}',
 'searchmenu-new' => '<strong>Crie a página "[[:$1]]" nesta wiki!</strong> {{PLURAL:$2|0=|Veja também a página encontrada na pesquisa.|Veja também os resultados da pesquisa.}}',
 'searchprofile-articles' => 'Páginas de conteúdo',
 'searchprofile-project' => 'Páginas de ajuda e de projeto',
@@ -1765,7 +1765,8 @@ Se optar por revelá-lo, ele será utilizado para atribuir-lhe crédito pelo seu
 'recentchanges-label-plusminus' => 'Alteração no tamanho da página, em bytes',
 'recentchanges-legend-heading' => "'''Legenda:'''",
 'recentchanges-legend-newpage' => '([[Special:NewPages|lista de páginas novas]])',
-'rcnotefrom' => 'Abaixo estão as mudanças desde <b>$2</b> (mostradas até <b>$1</b>).',
+'recentchanges-legend-plusminus' => '(<em>±123</em>)',
+'rcnotefrom' => 'Abaixo estão as mudanças desde <strong>$2</strong> (mostradas até <strong>$1</strong>).',
 'rclistfrom' => 'Mostrar as novas mudanças a partir das $1',
 'rcshowhideminor' => '$1 edições menores',
 'rcshowhideminor-show' => 'Mostrar',
@@ -2753,6 +2754,7 @@ Para referência é apresentado abaixo o último registo de bloqueio:',
 'sp-contributions-blocked-notice-anon' => 'Este endereço IP está bloqueado neste momento.
 Para referência é apresentado abaixo o último registo de bloqueio:',
 'sp-contributions-search' => 'Pesquisar contribuições',
+'sp-contributions-suppresslog' => 'contribuições suprimidas',
 'sp-contributions-username' => 'Endereço IP ou utilizador:',
 'sp-contributions-toponly' => 'Mostrar somente as revisões mais recentes',
 'sp-contributions-newonly' => 'Mostrar só edições que são criações de páginas',
@@ -4173,8 +4175,8 @@ Em conjunto com este programa deve ter recebido [{{SERVER}}{{SCRIPTPATH}}/COPYIN
 'revdelete-unrestricted' => 'restrições a administradores removidas',
 'logentry-move-move' => '$1 moveu a página $3 para $4',
 'logentry-move-move-noredirect' => '$1 moveu a página $3 para $4 sem deixar um redirecionamento',
-'logentry-move-move_redir' => '$1 moveu a página $3 para $4 sobre um redirecionamento',
-'logentry-move-move_redir-noredirect' => '$1 moveu a página $3 para $4 sobre um redirecionamento sem deixar um redirecionamento',
+'logentry-move-move_redir' => '$1 {{GENDER:$2|moveu}} a página $3 para $4 sobre um redirecionamento',
+'logentry-move-move_redir-noredirect' => '$1 {{GENDER:$2|moveu}} a página $3 para $4 sobre um redirecionamento sem deixar um redirecionamento',
 'logentry-patrol-patrol' => '$1 {{GENDER:$2|marcou}} a revisão $4 da página $3 como patrulhada',
 'logentry-patrol-patrol-auto' => '$1 {{GENDER:$2|marcou}} automaticamente a revisão $4 da página $3 como patrulhada',
 'logentry-newusers-newusers' => 'A conta de utilizador $1 foi {{GENDER:$2|criada}}',
index 5437018..0a48339 100644 (file)
@@ -9,6 +9,7 @@
  *
  * @author Alcali
  * @author Alchimista
+ * @author Anaclaudiaml
  * @author Bani
  * @author Brion
  * @author BrunaaAa
@@ -873,6 +874,8 @@ Por favor aguarde $1 antes de tentar novamente.',
 'suspicious-userlogout' => 'Sua solicitação para sair foi negada porque aparentemente foi enviada por um navegador danificado ou por um servidor proxy com cache.',
 'createacct-another-realname-tip' => 'O nome verdadeiro é opcional.
 Se você optar por fornecê-lo, este nome será utilizado para dar ao usuário a atribuição de seu trabalho.',
+'pt-login' => 'Entrar',
+'pt-createaccount' => 'Criar conta',
 
 # Email sending
 'php-mail-error-unknown' => 'Erro desconhecido na função mail() do PHP',
@@ -881,7 +884,7 @@ Se você optar por fornecê-lo, este nome será utilizado para dar ao usuário a
 
 # Change password dialog
 'changepassword' => 'Alterar senha',
-'resetpass_announce' => 'Você foi autenticado através de uma senha temporária. Para prosseguir, será necessário definir uma nova senha.',
+'resetpass_announce' => 'Para completar a autenticação, é necessário definir uma nova senha.',
 'resetpass_text' => '<!-- Adicionar texto aqui -->',
 'resetpass_header' => 'Alterar a senha da conta',
 'oldpassword' => 'Senha antiga',
@@ -897,8 +900,12 @@ Por favor, aguarde $1 antes de tentar novamente.',
 'resetpass-submit-cancel' => 'Cancelar',
 'resetpass-wrong-oldpass' => 'Senha temporária ou atual inválida.
 Você pode já ter alterado com sucesso a sua senha, ou solicitado uma nova senha temporária.',
+'resetpass-recycled' => 'Por favor, redefina sua nova senha para uma diferente da atual.',
+'resetpass-temp-emailed' => 'Você está autenticado com o código temporário enviado. Para finalizar a autenticação, você deve inserir uma nova senha aqui:',
 'resetpass-temp-password' => 'Senha temporária:',
 'resetpass-abort-generic' => 'Uma extensão cancelou a alteração da senha.',
+'resetpass-expired' => 'Sua senha expirou. Por favor insira uma nova senha para autenticar-se.',
+'resetpass-expired-soft' => 'Sua senha expirou e necessita ser resetada. Por favor escolha uma nova agora, ou clique "{{int:resetpass-submit-cancel}}" para resetar mais tarde.',
 
 # Special:PasswordReset
 'passwordreset' => 'Redefinir senha',
@@ -1407,7 +1414,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'nextn-title' => '{{PLURAL:$1|próximo|próximos}} $1 {{PLURAL:$1|resultado|resultados}}',
 'shown-title' => 'Mostrar $1 {{PLURAL:$1|resultado|resultados}} por página',
 'viewprevnext' => 'Ver ($1 {{int:pipe-separator}} $2) ($3).',
-'searchmenu-exists' => "'''Há uma página com o nome \"[[:\$1]]\" nesta wiki'''",
+'searchmenu-exists' => '<strong>Há uma página com o nome "[[:$1]]" neste wiki.</strong> {{PLURAL:$2|0=|Veja também os outros resultados da pesquisa encontrados.}}',
 'searchmenu-new' => '<strong>Criar a página "[[:$1]]" nesta wiki!</strong>{{PLURAL:$2|0=| Veja também a página encontrada com sua pesquisa.|Veja também os resultados das pesquisas encontradas.}}',
 'searchprofile-articles' => 'Páginas de conteúdo',
 'searchprofile-project' => 'Ajuda e páginas de projeto',
@@ -1756,11 +1763,23 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'rcnotefrom' => "Seguem as alterações desde as '''$4''' de '''$3''' (limitadas a '''$1''').",
 'rclistfrom' => 'Mostrar as novas alterações a partir das $1',
 'rcshowhideminor' => '$1 edições menores',
+'rcshowhideminor-show' => 'Exibir',
+'rcshowhideminor-hide' => 'Ocultar',
 'rcshowhidebots' => '$1 robôs',
+'rcshowhidebots-show' => 'Exibir',
+'rcshowhidebots-hide' => 'Ocultar',
 'rcshowhideliu' => '$1 usuários registrados',
+'rcshowhideliu-show' => 'Exibir',
+'rcshowhideliu-hide' => 'Ocultar',
 'rcshowhideanons' => '$1 usuários anônimos',
+'rcshowhideanons-show' => 'Exibir',
+'rcshowhideanons-hide' => 'Ocultar',
 'rcshowhidepatr' => '$1 edições patrulhadas',
+'rcshowhidepatr-show' => 'Exibir',
+'rcshowhidepatr-hide' => 'Ocultar',
 'rcshowhidemine' => '$1 minhas edições',
+'rcshowhidemine-show' => 'Exibir',
+'rcshowhidemine-hide' => 'Ocultar',
 'rclinks' => 'Exibir as $1 alterações recentes feitas nos últimos $2 dias<br />$3',
 'diff' => 'dif',
 'hist' => 'his',
@@ -1882,6 +1901,7 @@ Se você ainda quer enviar seu arquivo, volte e use um novo nome.
 'file-exists-duplicate' => 'Este arquivo é uma duplicata do seguinte {{PLURAL:$1|arquivo|arquivos}}:',
 'file-deleted-duplicate' => 'Um arquivo idêntico a este ([[:$1]]) foi eliminado anteriormente.
 Verifique o histórico de eliminação de tal arquivo antes de tentar re-enviar.',
+'file-deleted-duplicate-notitle' => 'Um arquivo idêntico a este foi anteriormente excluído, e o título foi suprimido. Você deve comunicar com alguém capaz de visualizar dados suprimidos, para verificar a situação antes de enviá-lo novamente.',
 'uploadwarning' => 'Aviso de envio',
 'uploadwarning-text' => 'Modifique a descrição do arquivo abaixo e tente novamente.',
 'savefile' => 'Salvar arquivo',
@@ -1894,6 +1914,7 @@ Verifique o histórico de eliminação de tal arquivo antes de tentar re-enviar.
 'php-uploaddisabledtext' => 'O envio de arquivos via PHP está desativado.
 Verifique a configuração file_uploads.',
 'uploadscripted' => 'Este arquivo contém HTML ou código que pode ser erroneamente interpretado por um navegador web.',
+'uploadscriptednamespace' => 'Este aruivo SVG contém um espaço nominal probido "$1"',
 'uploadinvalidxml' => 'O XML no arquivo enviado não pôde ser analisado.',
 'uploadvirus' => 'O arquivo contém vírus!
 Detalhes: $1',
@@ -2275,6 +2296,7 @@ Entradas <del>riscadas</del> foram resolvidas.',
 'protectedpages-unknown-timestamp' => 'Desconhecido',
 'protectedpages-unknown-performer' => 'Usuário desconhecido',
 'protectedtitles' => 'Títulos protegidos',
+'protectedtitles-summary' => 'Está página lista os títulos já protegidos de criação. Para ver a lista de páginas existentes que estão protegidas, consulte [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty' => 'Neste momento, nenhum dos títulos está protegido com estes parâmetros.',
 'listusers' => 'Lista de usuários',
 'listusers-editsonly' => 'Mostrar apenas usuários com edições',
@@ -2722,8 +2744,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Este endereço IP encontra-se bloqueado.
 Segue, para referência, a entrada mais recente no registro de bloqueios:',
 'sp-contributions-search' => 'Navegar pelas contribuições',
+'sp-contributions-suppresslog' => 'Contribuições de usuário eliminadas',
 'sp-contributions-username' => 'Endereço de IP ou usuário:',
 'sp-contributions-toponly' => 'Mostrar somente as edições que sejam a última alteração',
+'sp-contributions-newonly' => 'Mostrar somente as edições que criaram uma nova página.',
 'sp-contributions-submit' => 'Pesquisar',
 
 # What links here
@@ -3075,6 +3099,7 @@ Salve o arquivo no seu computador e importe-o aqui.',
 'import-error-special' => 'A página "$1" não pôde ser importada porque ela pertence a um espaço nominal especial que não suporta páginas.',
 'import-error-invalid' => 'A página "$1" não pôde ser importada por seu nome ser inválido.',
 'import-error-unserialize' => 'Revisão  $2  da página " $1 " não pôde ser desserializada. A revisão foi relatada para usar o modelo de conteúdo  $3  serializado como  $4',
+'import-error-bad-location' => 'A revisão $2, que usa o modelo de conteúdo $3, não pode ser gravada em "$1" nesta wiki, pois o modelo não é suportado nessa página.',
 'import-options-wrong' => '{{PLURAL:$2|Opção com erro|Opções com erros}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'A página raiz dada é um título inválido.',
 'import-rootpage-nosubpage' => 'O espaço nominal $1 da página principal não permite subpáginas.',
index 9e1240c..1bd3a45 100644 (file)
  * @author Od1n
  * @author Onecountry
  * @author Opraco
+ * @author Orlodrim
  * @author OsamaK
  * @author PhiLiP
  * @author Piangpha
  * @author Verdy p
  * @author Vinhtantran
  * @author Vivaelcelta
+ * @author Vriullop
  * @author Waldir
  * @author Whym
  * @author Yekrats
@@ -394,8 +396,10 @@ See also:
 Followed by a colon and a list of categories.
 
 Parameters:
-* $1 - number of hidden categories',
-'hidden-category-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where hidden categories will be listed.',
+* $1 - number of hidden categories
+{{Identical|Hidden category}}',
+'hidden-category-category' => 'Name of the [[mw:Help:Tracking categories|tracking category]] where hidden categories will be listed.
+{{Identical|Hidden category}}',
 'category-subcat-count' => 'This message is displayed at the top of a category page showing the number of pages in the category.
 
 Parameters:
@@ -657,8 +661,8 @@ See also:
 {{Identical|View}}',
 'toolbox' => 'The title of the toolbox below the search menu.
 {{Identical|Tool}}',
-'userpage' => '',
-'projectpage' => 'Used as link text in Talk page of project page.',
+'userpage' => 'Used in user talk pages as the text of the link to the user page, with the Cologne Blue skin.',
+'projectpage' => 'Used as link text in Talk page of project page with the Cologne Blue skin.',
 'imagepage' => 'Used as link text in Talk page of file page.',
 'mediawikipage' => 'Used as link text in Talk page of MediaWiki message page.',
 'templatepage' => 'Used as link text in Talk page of template page.',
@@ -1642,7 +1646,7 @@ Parameters:
 'resetpass-temp-password' => 'The label of the input box for the temporary password (received by email) on the form displayed after logging in with a temporary password.',
 'resetpass-abort-generic' => 'Generic error message shown on [[Special:ChangePassword]] when an extension aborts a password change from a hook.',
 'resetpass-expired' => "Generic error message shown on [[Special:ChangePassword]] when a user's password is expired",
-'resetpass-expired-soft' => 'Generic marning message shown on [[Special:ChangePassword]] when a user needs to reset their password, but they are not prevented from logging in at this time',
+'resetpass-expired-soft' => 'Generic warning message shown on [[Special:ChangePassword]] when a user needs to reset their password, but they are not prevented from logging in at this time',
 
 # Special:PasswordReset
 'passwordreset' => 'Title of [[Special:PasswordReset]].
@@ -3689,12 +3693,10 @@ Parameters:
 * $2 - a date and time
 * $3 - (Optional) a date
 * $4 - (Optional) a time',
-'rclistfrom' => 'Used on [[Special:RecentChanges]].
-
-Parameters:
-* $1 - Revision of a specific date and time. The date and the time adds to the rclistfrom description. No longer used.
-* $2 - Revision of a specific time. The time adds to the rclistfrom link description (with split of date and time).
-* $3 - Revision of a specific date. The date adds to the rclistfrom link description (with split of date and time).
+'rclistfrom' => 'Used on [[Special:RecentChanges]]. Parameters:
+* $1 - (Optional) date and time. The date and the time adds to the rclistfrom description.
+* $2 - time. The time adds to the rclistfrom link description (with split of date and time).
+* $3 - date. The date adds to the rclistfrom link description (with split of date and time).
 
 The corresponding message is {{msg-mw|Rcnotefrom}}.',
 'rcshowhideminor' => 'Option text in [[Special:RecentChanges]]. Parameters:
@@ -5934,7 +5936,19 @@ Parameters:
 {{Related|Protect-locked}}',
 'protect-cascadeon' => 'Used in Protection form.
 * $1 - number of cascade source pages',
-'protect-default' => '{{Identical|Default}}',
+'protect-default' => 'Describes the protection state of a page that allows all users to do a certain thing, like editing or moving the page. Example:
+
+<div style="border: 2px dotted gray; padding: .25cm">
+=={{int:Pageinfo-header-restrictions/en}}==
+{| class="wikitable"
+|-
+| {{int:Restriction-edit/en}}
+| {{int:Protect-default/en}}
+|-
+| {{int:Restriction-move/en}}
+| {{int:Protect-level-autoconfirmed/en}}
+|}
+</div>',
 'protect-fallback' => 'This message is used as an option in the protection form on wikis were extra protection levels have been configured.
 
 Parameters:
@@ -6350,6 +6364,9 @@ Anon version:
 * {{msg-mw|Sp-contributions-blocked-notice-anon}}',
 'sp-contributions-blocked-notice-anon' => 'Same as {{msg-mw|Sp-contributions-blocked-notice}} but for anonymous users.',
 'sp-contributions-search' => 'Used on [[Special:Contributions]]',
+'sp-contributions-suppresslog' => 'Used as a display name for a link to log entries of suppressed edits made by that user.
+
+Used as link title in [[Special:Contributions]] and in [[Special:DeletedContributions]].',
 'sp-contributions-username' => 'This message appears whenever someone requests [[Special:Contributions]].
 {{Identical|IP address or username}}',
 'sp-contributions-toponly' => '"top revision" means the "latest revision"',
@@ -8264,7 +8281,8 @@ This message is followed by the total number of times the page has been edited.'
 'pageinfo-magic-words' => 'The list of magic words on the page. Parameters:
 * $1 is the number of magic words on the page.',
 'pageinfo-hidden-categories' => 'The list of hidden categories on the page. Parameters:
-* $1 is the number of hidden categories on the page.',
+* $1 - the number of hidden categories on the page
+{{Identical|Hidden category}}',
 'pageinfo-templates' => 'The list of templates transcluded within the page. Parameters:
 * $1 is the number of templates transcluded within the current page.
 See also:
@@ -9001,12 +9019,14 @@ See also Wikipedia on [[w:Focal_length#In_photography|focal length]].',
 'exif-gpslatituderef' => 'In older versions of mediawiki this referred to if the latitude was North or South. This is no longer used in modern versions of mediawiki except for when using a foreign image repository that is using an older version of mediawiki since the information is now contained in {{msg-mw|exif-gpslatitude}}.
 {{Related|Exif-gpslatitude}}',
 'exif-gpslatitude' => 'The latitude of the location from where the picture was taken from.
-{{Related|Exif-gpslatitude}}',
+{{Related|Exif-gpslatitude}}
+{{Identical|Latitude}}',
 'exif-gpslongituderef' => 'Same as {{msg-mw|exif-gpslatituderef}} but for longitude.
 
 {{Related|Exif-gpslatitude}}',
 'exif-gpslongitude' => 'The longitude of the location from where the picture was taken from.
-{{Related|Exif-gpslatitude}}',
+{{Related|Exif-gpslatitude}}
+{{Identical|Longitude}}',
 'exif-gpsaltituderef' => 'No longer used except for when using foreign image repository with old version of mediawiki. 0 for above sea level, 1 for below sea level.',
 'exif-gpsaltitude' => 'Altitude in meters that the image was taken at.',
 'exif-gpstimestamp' => 'Time (does not include date) that GPS measurement was taken, in UTC. Since often this is at the same time as photo was taken, this is sometimes more reliable than {{msg-mw|exif-datetimeoriginal}}.',
index d427818..36bd2ea 100644 (file)
@@ -870,7 +870,7 @@ Pentru a finaliza acțiunea de autentificare, trebuie să setați o parolă nou
 'resetpass-temp-password' => 'Parolă temporară:',
 'resetpass-abort-generic' => 'Schimbarea parolei a fost anulată de către o extensie.',
 'resetpass-expired' => 'Parola dumneavoastră a expirat. Alegeți o parolă nouă pentru a vă autentifica.',
-'resetpass-expired-soft' => 'Parola dumneavoastră a expirat și trebuie schimbată. Alegeți o parolă nouă acum sau apăsați Revocare pentru a o reseta mai târziu.',
+'resetpass-expired-soft' => 'Parola dumneavoastră a expirat și trebuie schimbată. Alegeți o parolă nouă acum sau apăsați „{{int:resetpass-submit-cancel}}” pentru a o reseta mai târziu.',
 
 # Special:PasswordReset
 'passwordreset' => 'Resetare parolă',
@@ -1725,7 +1725,7 @@ Dacă decideți furnizarea sa, acesta va fi folosit pentru a vă atribui munca.'
 'recentchanges-legend-newpage' => '(vedeți și [[Special:NewPages|lista cu pagini noi]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
 'rcnotefrom' => 'Dedesubt sunt modificările începând cu <b>$2</b> (maximum <b>$1</b> afișate).',
-'rclistfrom' => 'Se arată modificările începând cu $1',
+'rclistfrom' => 'Se afișează modificările începând cu $1',
 'rcshowhideminor' => '$1 modificările minore',
 'rcshowhideminor-show' => 'Arată',
 'rcshowhideminor-hide' => 'Ascunde',
@@ -2700,6 +2700,7 @@ Ultima blocare este indicată mai jos pentru informare:',
 'sp-contributions-blocked-notice-anon' => 'Această adresă IP este blocată acum.
 Iată aici ultima înregistrare relevantă din jurnalul blocărilor:',
 'sp-contributions-search' => 'Căutare contribuții',
+'sp-contributions-suppresslog' => 'contribuții suprimate ale utilizatorului',
 'sp-contributions-username' => 'Adresă IP sau nume de utilizator:',
 'sp-contributions-toponly' => 'Afișează numai versiunile recente',
 'sp-contributions-newonly' => 'Afișează numai modificările care au dus la crearea de pagini',
index f0fc215..5d425d1 100644 (file)
@@ -591,7 +591,7 @@ Ce tu scacchie de metterle, quiste avène ausate pe dà 'u giuste merite a 'a fa
 
 # Change password dialog
 'changepassword' => "Cange 'a password",
-'resetpass_announce' => "Tu tè colleghete cu 'nu codece mannete pe e-mail temboranee.
+'resetpass_announce' => "Tu tè collegate cu 'nu codece mannate pe e-mail temboranèe.
 Pe spiccià 'a procedure de collegamende, tu a 'mbostà 'na password nove aqquà:",
 'resetpass_text' => "<!-- Mitte 'u teste aqquà -->",
 'resetpass_header' => "Cange 'a password d'u cunde utende",
@@ -1461,7 +1461,7 @@ Ce tu 'u mitte, a fatje ca è fatte t'avène ricanusciute.",
 'recentchanges-label-unpatrolled' => "Stu cangiamende non g'à state angore condrollate",
 'recentchanges-legend-heading' => "'''Leggende:'''",
 'recentchanges-legend-newpage' => "('ndruche pure [[Special:NewPages|elenghe de le pàggene nuève]])",
-'rcnotefrom' => "Sotte stonne le cangiaminde da '''$2''' (fine a '''$1''' mustrete).",
+'rcnotefrom' => "Sotte stonne le cangiaminde da '''$2''' ('nzigne a '''$1''' fatte vedè).",
 'rclistfrom' => 'Fà vedè le urteme cangiaminde partenne da $1',
 'rcshowhideminor' => '$1 cangiaminde stuèdeche',
 'rcshowhidebots' => '$1 bot',
@@ -1600,6 +1600,7 @@ Avissa verificà 'a storie d'a scangellazzione d'u file apprime de condinuà a c
 'php-uploaddisabledtext' => "Le carecaminde de file sonde disabilitate in PHP.<br />
 Pe piacere verifiche le 'mbostaziune d'u ''file_uploads''.",
 'uploadscripted' => "Stu file condene HTML o codece de script ca ponne essere inderpretete jndr'à 'nu mode sbagliete da le browser.",
+'uploadscriptednamespace' => "Stu file SVG tène 'nu namespace illegale '$1'",
 'uploadinvalidxml' => "L'XML jndr'à 'u file carecate non ge pò essere analizzate.",
 'uploadvirus' => "Alanga toje, 'u file condiene 'nu virus! Dettaglie: $1",
 'uploadjava' => "'U file jè 'nu file de tipe ZIP ca condene 'nu file de classe Java.
index 9253b4c..88aaa50 100644 (file)
@@ -2855,6 +2855,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Этот IP-адрес в данный момент заблокирован.
 Ниже приведена последняя запись из журнала блокировок:',
 'sp-contributions-search' => 'Поиск вклада',
+'sp-contributions-suppresslog' => 'удалённый вклад участника',
 'sp-contributions-username' => 'IP-адрес или имя участника:',
 'sp-contributions-toponly' => 'Показывать только правки, являющиеся последними версиями',
 'sp-contributions-newonly' => 'Показывать только правки, являющиеся созданием страниц',
index 5404ea8..e4bf359 100644 (file)
@@ -512,7 +512,8 @@ $2',
 'invalidtitle-knownnamespace' => 'Непряавилна назва в просторї назв „$2“ і текстом „$3“',
 'invalidtitle-unknownnamespace' => 'Неправилна назва з незнамым чіслом простору назв $1 і текстом „$2“',
 'exception-nologin' => 'Не сьте приголошеный(а)',
-'exception-nologin-text' => 'Гевся сторінка або дїя потребує, жебы сьте были на тотїй вікі приголошены.',
+'exception-nologin-text' => 'Жебы ся дістати но тоту сторінку ся просиме [[Special:Userlogin|приголосьте]].',
+'exception-nologin-text-manual' => 'Жебы ся дістати на тоту сторінку ся мусите $1.',
 
 # Virus scanner
 'virus-badscanner' => "Зла конфіґурація: незнамый антивіровый проґрам: ''$1''",
@@ -562,6 +563,8 @@ $2',
 'userlogin-resetpassword-link' => 'Забыли сьте гесло?',
 'helplogin-url' => 'Help:Приголошіня',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Поміч з приголошованём]]',
+'userlogin-loggedin' => 'Уж сьте {{GENDER:$1|приголошеный|приголошена}} як $1.
+Хоснуйте формулар долов жебы сьте ся приголосили як другый хоснователь.',
 'userlogin-createanother' => 'Створити інше конто',
 'createacct-join' => 'Ниже уведьте вашы інформації',
 'createacct-another-join' => 'Ниже уведьте інформації нового конта',
@@ -628,8 +631,8 @@ $2',
 Жебы ся то не зловжывало та гесло може быти заслане лем раз за $1 {{PLURAL:$1|годину|годины|годин}}.',
 'mailerror' => 'Хыба засыланя ел. пошты: $1',
 'acct_creation_throttle_hit' => 'Хоснователї приходячі з вашой IP адресы уж днесь створили {{PLURAL:$1|конто|конта|конт}}, што є дозволене максімум. Зато теперь не є дозволено з той IP адресы закладати далшы конта.',
-'emailauthenticated' => 'Ð\90дÑ\80еÑ\81а Ð²Ð°Ñ\88ой ÐµÐ». Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ð±Ñ\8bла Ð¾Ð²Ñ\96Ñ\80ена Ð´Ð½Ñ\8f $2 о $3.',
-'emailnotauthenticated' => 'Ð\90дÑ\80еÑ\81а Ð²Ð°Ñ\88ой ÐµÐ». Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ð´Ð¾Ñ\82епеÑ\80Ñ\8c Ð½Ðµ Ð±Ñ\8bла Ð¾Ð²Ñ\96Ñ\80ена, Ñ\84Ñ\83нкÑ\86Ñ\96Ñ\97 ÐµÐ». Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ñ\81Ñ\83Ñ\82Ñ\8c Ð½ÐµÐ´Ð¾Ñ\81Ñ\82Ñ\83пны.',
+'emailauthenticated' => 'Ð\90дÑ\80еÑ\81а Ð²Ð°Ñ\88ой ÐµÐ». Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ð±Ñ\8bла Ð¿Ð¾Ñ\82веÑ\80джнена $2 о $3.',
+'emailnotauthenticated' => 'Ð\90дÑ\80еÑ\81а Ð²Ð°Ñ\88ой ÐµÐ». Ð¿Ð¾Ñ\88Ñ\82Ñ\8b Ð´Ð¾Ñ\82епеÑ\80Ñ\8c Ð½Ðµ Ð±Ñ\8bла Ð¿Ð¾Ñ\82веÑ\80ждена. Ð£ Ð½Ð°Ñ\81Ñ\82Ñ\83пнÑ\8bÑ\85 Ñ\84Ñ\83нкÑ\86Ñ\96й Ð½Ðµ Ð±Ñ\83дÑ\83Ñ\82Ñ\8c Ð¿Ð¾Ñ\81Ñ\8bланÑ\8b Ð¶Ð°Ð´Ð½Ñ\8b Ð¼ÐµÐ¹Ð»ы.',
 'noemailprefs' => 'Шпеціфікуйте адресу ел. пошты, жебы наслїднуючі можности могли фунґовати.',
 'emailconfirmlink' => 'Потвердьте свою адресу ел. пошты',
 'invalidemailaddress' => 'Уведена адреса ел. пошты не може быти прията, бо она не має правилный формат.
@@ -650,6 +653,9 @@ $2',
 'suspicious-userlogout' => 'Ваша пожадавка на одголошіня была одвергнута, бо вызерає то так, же была послана розбитым переглядачом або кешуючім проксі-сервером.',
 'createacct-another-realname-tip' => 'Правдиве імя є волительне.
 Кідь вы зволите го додати, тото буде пак хосноване на доданя участникового попису про ёго роботу.',
+'pt-login' => 'Приголошіня',
+'pt-createaccount' => 'Створити конто',
+'pt-userlogout' => 'Одголосити ся',
 
 # Email sending
 'php-mail-error-unknown' => 'Незнама хыба у PHP mail() функції',
@@ -658,21 +664,27 @@ $2',
 
 # Change password dialog
 'changepassword' => 'Змінити гесло',
-'resetpass_announce' => 'Ð\9fÑ\80иголоÑ\88Ñ\83Ñ\94Ñ\82е Ñ\81Ñ\8f Ð´Ð¾Ñ\87аÑ\81нÑ\8bм Ð³ÐµÑ\81лом, ÐºÐ¾Ñ\82Ñ\80е Ð±Ñ\8bло Ð¿Ð¾Ñ\81лане ÐµÐ»ÐµÐºÑ\82Ñ\80онÑ\96Ñ\87нов Ð¿Ð¾Ñ\88Ñ\82ов. Ð\9fÑ\80о Ð·Ð°ÐºÐ¾Ð½Ñ\87Ñ\96нÑ\8f Ð¿Ñ\80иголоÑ\88Ñ\96нÑ\8f Ñ\82Ñ\80еба Ð·Ð°Ð´Ð°Ñ\82и Ð½Ð¾Ð²Ðµ Ð³ÐµÑ\81ло Ñ\82Ñ\83:',
+'resetpass_announce' => 'Ð\96ебÑ\8b Ñ\81Ñ\8cÑ\82е Ð·Ð°Ð²ÐµÑ\80Ñ\88Ñ\8bли Ð¿Ñ\80иголоÑ\88Ñ\96нÑ\8f, Ð¼Ñ\83Ñ\81иÑ\82е Ñ\81обÑ\96 Ð½Ð°Ñ\81Ñ\82авиÑ\82и Ð½Ð¾Ð²Ðµ Ð³ÐµÑ\81ло.',
 'resetpass_header' => 'Зміна гесла',
 'oldpassword' => 'Старе гесло:',
 'newpassword' => 'Нове гесло:',
 'retypenew' => 'Напиште знову нове гесло:',
 'resetpass_submit' => 'Наставити гесло і приголосити ся',
 'changepassword-success' => 'Ваше гесло было успішно змінено!',
+'changepassword-throttled' => 'Зробили сьте дуже много спроб о приголошіня.
+Просиме Вас, почекайте $1 перед далшов спробов.',
 'resetpass_forbidden' => 'Гесла не є можне змінити',
 'resetpass-no-info' => 'Ку тій сторінцї мають прямый приступ лем приголошены хоснователї.',
 'resetpass-submit-loggedin' => 'Змінити гесло',
 'resetpass-submit-cancel' => 'Сторно',
 'resetpass-wrong-oldpass' => 'Неправилне дочасне або актуалне гесло.
 Може сьте собі уж гесло успішно змінили, або сьте выжадали нове дочасне гесло.',
+'resetpass-recycled' => 'Нове гесло собі дайте дашто друге як ваше теперїшнє гесло.',
+'resetpass-temp-emailed' => 'Приголошуєте ся дочасным геслом засланым імейлом.
+Жебы сьте завершыли приголошіня, гев сові наставте нове гесло:',
 'resetpass-temp-password' => 'Дочасне гесло:',
 'resetpass-abort-generic' => 'Зміна гесла заблокована была росшырїнём.',
+'resetpass-expired' => 'Платность вашого гесла скінчіла. На приголошіня собі наставте нове гесло.',
 
 # Special:PasswordReset
 'passwordreset' => 'Ресет гесла',
@@ -719,6 +731,8 @@ $2
 'changeemail-password' => 'Ваше гесло на портал {{SITENAME}}:',
 'changeemail-submit' => 'Змінити імейл',
 'changeemail-cancel' => 'Сторно',
+'changeemail-throttled' => 'Зробили сьте дуже много спроб о приголошіня.
+Просиме Вас, почекайте $1 перед далшов спробов.',
 
 # Special:ResetTokens
 'resettokens' => 'Реініціалізація клічів',
@@ -1155,7 +1169,7 @@ $1",
 'shown-title' => 'Вказати $1 {{PLURAL:$1|резултат|резултаты|резултатів}} на сторінку',
 'viewprevnext' => 'Перегляднути ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''У тій вікі є сторінка з назвов «[[:$1]]»'''",
-'searchmenu-new' => "'''Створити сторінку «[[:$1]]» у тій вікі!'''",
+'searchmenu-new' => '<strong>Створити сторінку на тій вікі „[[:$1]]“!</strong> {{PLURAL:$2|0=|Тыж собі посмотьте сторінку найдену вашым гляданём.|Тыж посмотьте сторінкы найдены вашым гляданём.}}',
 'searchprofile-articles' => 'Статї',
 'searchprofile-project' => 'Сторінкы помочі і проєкту',
 'searchprofile-images' => 'Мултімедія',
@@ -1491,15 +1505,28 @@ $1",
 'recentchanges-label-minor' => 'Тото є мала зміна',
 'recentchanges-label-bot' => 'Тото едітованя зроблене ботом',
 'recentchanges-label-unpatrolled' => 'Тота зміна дотеперь не была патролёвана.',
+'recentchanges-legend-heading' => "'''Леґенда:'''",
 'recentchanges-legend-newpage' => '$1 — нова сторінка',
-'rcnotefrom' => 'Ð\9dиже {{PLURAL:$1|Ñ\94\81Ñ\83Ñ\82Ñ\8c\94}} Ð½Ð°Ð¹Ð²ÐµÑ\86е <b>$1</b> {{PLURAL:$1|змÑ\96на|змÑ\96нÑ\8b|змÑ\96н}} Ð¾Ð´ <b>$2</b>.',
+'rcnotefrom' => 'Ð\94олов Ñ\81Ñ\83Ñ\82Ñ\8c Ð²ÐºÐ°Ð·Ð°Ð½Ñ\8b Ð·Ð¼Ñ\96нÑ\8b Ð¾Ð´ <strong>$2</strong> (до <strong>$1</strong>).',
 'rclistfrom' => 'Вказати едітованя почінаючі з $1.',
 'rcshowhideminor' => '$1 маленькы едітованя',
+'rcshowhideminor-show' => 'Вказати',
+'rcshowhideminor-hide' => 'Сховати',
 'rcshowhidebots' => '$1 ботів',
-'rcshowhideliu' => '$1 приголошеных',
+'rcshowhidebots-show' => 'Вказати',
+'rcshowhidebots-hide' => 'Сховати',
+'rcshowhideliu' => '$1 реґістрованых хоснователїв',
+'rcshowhideliu-show' => 'Вказати',
+'rcshowhideliu-hide' => 'Сховати',
 'rcshowhideanons' => '$1 анонімів',
+'rcshowhideanons-show' => 'Вказати',
+'rcshowhideanons-hide' => 'Сховати',
 'rcshowhidepatr' => '$1 перевірене едітованя',
+'rcshowhidepatr-show' => 'Вказати',
+'rcshowhidepatr-hide' => 'Сховати',
 'rcshowhidemine' => '$1 мої едітованя',
+'rcshowhidemine-show' => 'Вказати',
+'rcshowhidemine-hide' => 'Сховати',
 'rclinks' => 'Вказати послїднї $1 зміны за $2 днїв<br />$3',
 'diff' => 'різн.',
 'hist' => 'історія',
@@ -1969,6 +1996,11 @@ $1',
 'protectedpages-indef' => 'Лем замкы на нестановлено',
 'protectedpages-cascade' => 'Лем каскадовы замкы',
 'protectedpagesempty' => 'Жадна сторінка не є замкнута з тыма параметрами.',
+'protectedpages-timestamp' => 'Часова значка',
+'protectedpages-expiry' => 'Кінчіть',
+'protectedpages-reason' => 'Прічіна',
+'protectedpages-unknown-timestamp' => 'Не є знаме',
+'protectedpages-unknown-performer' => 'Незнамый хоснователь',
 'protectedtitles' => 'Замкнуты назвы сторінок',
 'protectedtitlesempty' => 'Жадна назва не є замкнута з тыма параметрами.',
 'listusers' => 'Список хоснователїв',
@@ -2388,7 +2420,7 @@ $1',
 'contributions' => 'Приспівкы {{GENDER:$1|хоснователя|хоснователькы}}',
 'contributions-title' => 'Приспівок хоснователя $1',
 'mycontris' => 'Приспівкы',
-'contribsub2' => 'Приспівок $1 ($2)',
+'contribsub2' => '{{GENDER:$3|хоснователї|хоснователькы}} $1 ($2)',
 'nocontribs' => 'Ненайджены жадны зміны за тыма крітеріями.',
 'uctop' => '(остатня)',
 'month' => 'Од місяця (і скоре):',
@@ -2698,6 +2730,7 @@ $1',
 'allmessages-prefix' => 'Філтер за префіксом:',
 'allmessages-language' => 'Язык:',
 'allmessages-filter-submit' => 'Выконати',
+'allmessages-filter-translate' => 'Переложыти',
 
 # Thumbnails
 'thumbnail-more' => 'Звекшыти',
@@ -2967,7 +3000,7 @@ $1',
 'svg-long-desc' => 'SVG-файл, номінално $1 × $2 пікселів, розмір файлу: $3',
 'svg-long-desc-animated' => 'Анімованый SVG-файл, номінално $1 × $2 пікселів, розмір файлу: $3',
 'svg-long-error' => 'Неправильный файл SVG: $1',
-'show-big-image' => 'Ð\9fовне Ñ\80озлиÑ\88Ñ\96нÑ\8f',
+'show-big-image' => 'Ð\9eÑ\80Ñ\96Ò\91Ñ\96налнÑ\8bй Ñ\84айл',
 'show-big-image-preview' => 'Розмір того нагляду: $1.',
 'show-big-image-other' => '{{PLURAL:$2|Інше|іншы}} розлишіня: $1.',
 'show-big-image-size' => '$1 × $2 пікселів',
index ae3e444..d184baa 100644 (file)
@@ -18,6 +18,7 @@
  * @author Krinkle
  * @author Mahitgar
  * @author Naveen Sankar
+ * @author NehalDaveND
  * @author Omnipaedista
  * @author Shantanoo
  * @author Shijualex
@@ -1016,6 +1017,7 @@ $2
 प्रतीयते यदिदं अपाकृतमस्ति।',
 'edit-conflict' => 'सम्पादनयोः/सम्पादनानां अन्तर्विरोधः।',
 'edit-no-change' => 'भवतः सम्पादनम् उपेक्षितम्, यतो हि भवता पाठे न किमपि परिवर्तनं कृतम्।',
+'postedit-confirmation' => 'सम्पादनं रक्षितम् ।',
 'edit-already-exists' => 'नूतनं पृष्ठं स्रष्टुं नापारयत्।
 इदं पूर्वे एव विद्यते।',
 'defaultmessagetext' => 'सन्देशपाठं स्थिरयतु ।',
index 38b0400..0f8b885 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author (vinny)
+ * @author AmaryllisGardener
  * @author Avicennasis
  * @author Derek Ross
  * @author John Reid
@@ -29,34 +30,35 @@ $messages = array(
 'tog-hideminor' => 'Skauk smaa eidits in recent chynges',
 'tog-hidepatrolled' => 'Skauk patrolled eidits in recent chynges',
 'tog-newpageshidepatrolled' => 'Skauk patrolled pages frae the new page leet',
-'tog-extendwatchlist' => 'Mak watchleet bigger tae shaw aw chynges,no jyst the maist recent',
-'tog-usenewrc' => 'Groop chynges bi page in recent chynges and watchleet',
+'tog-extendwatchlist' => 'Mak watchleet bigger tae shaw aw chynges, no just the maist recent',
+'tog-usenewrc' => 'Groop chynges bi page in recent chynges n watchleet',
 'tog-numberheadings' => 'Auto-nummer heidins',
 'tog-showtoolbar' => 'Shaw eidit tuilbaur',
 'tog-editondblclick' => 'Eidit pages oan dooble-clap (JavaScript)',
 'tog-editsectiononrightclick' => 'Enable section editin bi richt-clapin on section teitles',
 'tog-rememberpassword' => 'Mynd ma password oan this browser (fer ae maximum o $1 {{PLURAL:$1|day|days}})',
-'tog-watchcreations' => 'Add pages that Ah mak an files Ah uplaid til ma watchleet',
+'tog-watchcreations' => 'Add pages that Ah cræft n files that Ah uplaid til ma watchleet',
 'tog-watchdefault' => 'Add pages an files that Ah edit til ma watchleet',
 'tog-watchmoves' => 'Eik pages an files that Ah muiv til ma watchleet',
-'tog-watchdeletion' => 'Eik pages an files that Ah get rid o til ma watchleet',
+'tog-watchdeletion' => 'Eik pages n files that Ah get rid o til ma watchleet',
 'tog-minordefault' => 'Mairk aa edits "smaa" bi defaut',
-'tog-previewontop' => 'Shaw owerview afore eidit kist an no efter it',
-'tog-previewonfirst' => 'Shaw scance oan firstwhile eidit',
+'tog-previewontop' => 'Shaw owerview afore eidit kist n no efter it',
+'tog-previewonfirst' => 'Shaw luikower oan firstwhile eidit',
 'tog-enotifwatchlistpages' => 'Wab-mail me whan ae page or file on ma watchleet is chynged',
 'tog-enotifusertalkpages' => 'Send me ae wab-mail whan ma uiser tauk page is chynged',
 'tog-enotifminoredits' => 'Send me ae wab-mail fer wee edits o pages an files ava',
 'tog-enotifrevealaddr' => 'Shaw ma email address in notification mails',
 'tog-shownumberswatching' => 'Shaw the nummer o watching uisers',
+'tog-oldsig' => 'Existin signatur:',
 'tog-fancysig' => 'Treat signature as wikitext (wioot aen autæmatic airtin)',
 'tog-uselivepreview' => 'Uise live preview (experimental)',
-'tog-forceeditsummary' => 'Gie me a jottin when A dinnae put in aen eidit owerview',
+'tog-forceeditsummary' => 'Gie me ae jottin when Ah dinnae put in aen eidit owerview',
 'tog-watchlisthideown' => 'Skauk ma eidits frae the watchleet',
 'tog-watchlisthidebots' => 'Skauk bot eidits frae the watchleet',
 'tog-watchlisthideminor' => 'Dinna shaw smaa eidits oan ma watchleet',
-'tog-watchlisthideliu' => 'Skauk eidits bi loggit in uisers frae the watchleet',
-'tog-watchlisthideanons' => 'Skauk eidits bi nameless uisers frae the watchleet',
-'tog-watchlisthidepatrolled' => 'Skauk patrolled eidits frae the watchlist',
+'tog-watchlisthideliu' => 'Skauk eidits bi loggit in uisers fae the watchleet',
+'tog-watchlisthideanons' => 'Skauk eidits bi nameless uisers fae the watchleet',
+'tog-watchlisthidepatrolled' => 'Skauk patrolled eidits fae the watchleet',
 'tog-ccmeonemails' => 'Gie me copies o emails A write tae ither uisers',
 'tog-diffonly' => 'Dinna shaw page contents ablo diffs',
 'tog-showhiddencats' => "Shaw Skauk't categeries",
@@ -80,8 +82,8 @@ $messages = array(
 'tuesday' => 'Tysday',
 'wednesday' => 'Wadensday',
 'thursday' => 'Fuirsday',
-'friday' => 'Friday',
-'saturday' => 'Seturday',
+'friday' => 'Fryday',
+'saturday' => 'Setturday',
 'sun' => 'Sun',
 'mon' => 'Mon',
 'tue' => 'Tue',
@@ -92,7 +94,7 @@ $messages = array(
 'january' => 'Januair',
 'february' => 'Febuair',
 'march' => 'Mairch',
-'april' => 'Apryle',
+'april' => 'Aprile',
 'may_long' => 'Mey',
 'june' => 'Juin',
 'july' => 'Julie',
@@ -102,9 +104,9 @@ $messages = array(
 'november' => 'November',
 'december' => 'December',
 'january-gen' => 'Januair',
-'february-gen' => 'February',
+'february-gen' => 'Februar',
 'march-gen' => 'Mairch',
-'april-gen' => 'Apryle',
+'april-gen' => 'Aprile',
 'may-gen' => 'Mey',
 'june-gen' => 'Juin',
 'july-gen' => 'Julie',
@@ -112,7 +114,7 @@ $messages = array(
 'september-gen' => 'September',
 'october-gen' => 'October',
 'november-gen' => 'November',
-'december-gen' => 'Dizember',
+'december-gen' => 'December',
 'jan' => 'Jan',
 'feb' => 'Feb',
 'mar' => 'Mai',
@@ -131,7 +133,7 @@ $messages = array(
 'april-date' => '$1 Apryl',
 'may-date' => '$1 Mey',
 'june-date' => '$1 Juin',
-'july-date' => '$1 Juli',
+'july-date' => '$1 Julie',
 'august-date' => '$1 August',
 'september-date' => '$1 September',
 'october-date' => '$1 October',
@@ -167,7 +169,7 @@ $messages = array(
 'mytalk' => 'Ma tauk',
 'anontalk' => 'Tauk fer this IP address',
 'navigation' => 'Navigation',
-'and' => '&#32;an',
+'and' => '&#32;n',
 
 # Cologne Blue skin
 'qbfind' => 'Rake',
@@ -212,13 +214,13 @@ $messages = array(
 'view' => 'View.',
 'edit' => 'Eidit',
 'create' => 'Mak',
-'editthispage' => 'Eidit this page',
+'editthispage' => 'Eedit this page',
 'create-this-page' => 'Mak this page',
 'delete' => 'Delyte',
 'deletethispage' => 'Delyte this page',
 'undeletethispage' => 'Ondelyte this page',
 'undelete_short' => 'Undelete {{PLURAL:$1|ane edit|$1 edits}}',
-'viewdeleted_short' => 'View {{PLURAL:$1|yin deletit eidit|$1 deletit eidits}}',
+'viewdeleted_short' => 'See {{PLURAL:$1|yin delytit eedit|$1 delytit eedits}}',
 'protect' => 'Fend',
 'protect_change' => 'chynge',
 'protectthispage' => 'Fend this page',
@@ -229,13 +231,13 @@ $messages = array(
 'talkpagelinktext' => 'Tauk',
 'specialpage' => 'Byordinar Page',
 'personaltools' => 'Personal tuils',
-'postcomment' => 'Eik a message',
+'postcomment' => 'New section',
 'articlepage' => 'Leuk at content page',
 'talk' => 'Collogue',
 'views' => 'Views',
 'toolbox' => 'Tuilkist',
 'userpage' => 'View uiser page',
-'projectpage' => 'View project page',
+'projectpage' => 'See waurk page',
 'imagepage' => 'look ower image page',
 'mediawikipage' => 'View message page',
 'templatepage' => 'View template page',
@@ -294,11 +296,11 @@ $1',
 'newmessageslinkplural' => '{{PLURAL:$1|ae new message|999=new messages}}',
 'newmessagesdifflinkplural' => 'last {{PLURAL:$1|chynge|999=chynges}}',
 'youhavenewmessagesmulti' => 'Ye hae new messages oan $1',
-'editsection' => 'eidit',
-'editold' => 'eidit',
+'editsection' => 'eedit',
+'editold' => 'eedit',
 'viewsourceold' => 'ken soorce',
 'editlink' => 'eidit',
-'viewsourcelink' => 'Scance ower the source',
+'viewsourcelink' => 'view soorce',
 'editsectionhint' => 'Eidit section: $1',
 'toc' => 'Table o contents',
 'showtoc' => 'shaw',
@@ -307,7 +309,7 @@ $1',
 'collapsible-expand' => 'Mak mair muckle',
 'thisisdeleted' => 'View or cower $1?',
 'viewdeleted' => 'View $1?',
-'restorelink' => '{{PLURAL:$1|yin delyte eidit|$1 delyte eidits}}',
+'restorelink' => '{{PLURAL:$1|yin delytit eidit|$1 delytit eidits}}',
 'feedlinks' => 'Feed:',
 'feed-invalid' => "This feeds subscrieve's teep isnae habile.",
 'feed-unavailable' => 'Syndication feeds isna available',
@@ -324,7 +326,7 @@ $1',
 'nstab-user' => 'Uiser page',
 'nstab-media' => 'Eetem page',
 'nstab-special' => 'Byordinar page',
-'nstab-project' => 'Project page',
+'nstab-project' => 'Waurk page',
 'nstab-image' => 'Eimage',
 'nstab-mediawiki' => 'Message',
 'nstab-template' => 'Template',
@@ -348,7 +350,7 @@ A leet o valid byordinar pages can be funnd at [[Special:SpecialPages|{{int:spec
 This micht be cause o ae bug in the saffware.',
 'databaseerror-textcl' => 'Ae database speirin mistak has occurred.',
 'databaseerror-query' => 'Speirin: $1',
-'databaseerror-function' => 'Fwnction: $1',
+'databaseerror-function' => 'Function: $1',
 'databaseerror-error' => 'Mistake: $1',
 'laggedslavemode' => '<strong>Warnishment:</strong> Page micht no contain recent updates',
 'readonly' => 'Database lockit',
@@ -391,18 +393,18 @@ It gae nae explanâtion.',
 'perfcachedts' => 'The followin data is cached, an wis hindermaist updated $1. Ae maximum o {{PLURAL:$4|yin result is|$4 results ar}} available in the cache.',
 'querypage-no-updates' => 'Updates for this page ar disablit at the meenit. Data here wilnae be refreshit at the meenit.',
 'viewsource' => 'View soorce',
-'viewsource-title' => 'View source fer $1',
+'viewsource-title' => 'View soorce fer $1',
 'actionthrottled' => 'Action devalit',
-'actionthrottledtext' => 'As an anti-spam meisur, ye ar limitit frae daein this action ower mony times in a ower short tid, an ye hae exceedit this limit. Please try again in a wee.',
+'actionthrottledtext' => "Aes aen anti-spam meisur, ye'r limitit fae daein this action ower monie times in aen ower short time, n ye'v exceedit this limit. Please try again in ae few minutes.",
 'protectedpagetext' => 'This page haes been protected fer tae prevent eiditing or ither actions.',
-'viewsourcetext' => 'Ye can leuk at an copy the soorce o this page:',
-'viewyourtext' => 'Ye can view an copy the source o <strong>yer eidits</strong> til this page:',
+'viewsourcetext' => 'Ye can leuk at n copie the soorce o this page:',
+'viewyourtext' => 'Ye can see n copie the soorce o <strong>yer eedits</strong> til this page:',
 'protectedinterface' => 'This page provides interface tex fer the saffware oan this wiki, n is protected fer tae prevent abuise.
 Tae add or chynge owersets fer aw wikis, please uise [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.',
 'editinginterface' => "<strong>Warnishment:</strong> Ye'r eiditing ae page that is uised tae provide interface tex fer the saffware.
 Chynges til this page will affect the appearance o the uiser interface fer ither uisers oan this wiki.
 Tae add or chynge owersets fer aw wikis, please uise [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.",
-'cascadeprotected' => 'This page haes been protectit fae editin, cause it is inclædit in the follaein {{PLURAL:$1|page|pages}}, that ar protectit wi the "cascadin" optie turnit oan:
+'cascadeprotected' => 'This page haes been protectit fae eiditin, cause it is inclædit in the follaein {{PLURAL:$1|page|pages}}, that ar protectit wi the "cascadin" optie turnit oan:
 $2',
 'namespaceprotected' => "Ye dinna hae permeession tae edit pages in the '''$1''' namespace.",
 'customcssprotected' => "Ye dinna hae permeession tae eidit this CSS page cause it contains anither uiser's personal settings.",
@@ -439,23 +441,23 @@ Ye can chynge yer {{SITENAME}} [[Special:Preferences|preferences]] gif ye like.'
 'userlogin-yourname' => 'Uisername',
 'userlogin-yourname-ph' => 'Enter yer uisername',
 'createacct-another-username-ph' => 'Enter the uisername',
-'yourpassword' => 'Passwaird:',
-'userlogin-yourpassword' => 'Password.',
-'userlogin-yourpassword-ph' => 'Enter yer password',
-'createacct-yourpassword-ph' => 'Enter ae password',
-'yourpasswordagain' => 'Retype passwaird:',
-'createacct-yourpasswordagain' => 'Confirm password.',
-'createacct-yourpasswordagain-ph' => 'Enter password again.',
+'yourpassword' => 'Passwird:',
+'userlogin-yourpassword' => 'Passwaird.',
+'userlogin-yourpassword-ph' => 'Enter yer passwaird',
+'createacct-yourpassword-ph' => 'Enter ae passwaird',
+'yourpasswordagain' => 'Retype passwird:',
+'createacct-yourpasswordagain' => 'Confirm passwaird.',
+'createacct-yourpasswordagain-ph' => 'Enter passwaird again.',
 'remembermypassword' => 'Mynd ma login oan this brouser (fer $1 {{PLURAL:$1|day|days}} at the maist)',
 'userlogin-remembermypassword' => 'Keep me loggit in',
 'userlogin-signwithsecure' => 'Uise secure connection',
 'yourdomainname' => 'Yer domain:',
 'password-change-forbidden' => 'Ye canna chynge passwords oan this wiki.',
-'externaldberror' => "Aither the wis an external authenteication database mishanter, or ye'r no alloued tae update yer external accoont.",
+'externaldberror' => "Aither thaur wis aen external authentication database mistak, or ye'r no permitit tae update yer external accoont.",
 'login' => 'Log in',
 'nav-login-createaccount' => 'Log in / mak an accoont',
 'loginprompt' => 'Ye maun hae cookies enabled tae log in tae {{SITENAME}}.',
-'userlogin' => 'Mak an accoont or log in',
+'userlogin' => 'Cræft aen accoont or log in',
 'userloginnocreate' => 'Log in.',
 'logout' => 'Log oot',
 'userlogout' => 'Log oot',
@@ -463,7 +465,7 @@ Ye can chynge yer {{SITENAME}} [[Special:Preferences|preferences]] gif ye like.'
 'userlogin-noaccount' => 'Dinna hae aen accoont?',
 'userlogin-joinproject' => 'Jyn {{SITENAME}}',
 'nologin' => "Dinna hae an accoont? '''$1'''.",
-'nologinlink' => 'Mak an accoont',
+'nologinlink' => 'Cræft aen accoont',
 'createaccount' => 'Mak new accoont',
 'gotaccount' => "Got an accoont afore? '''$1'''.",
 'gotaccountlink' => 'Log in',
@@ -480,7 +482,7 @@ Uise the form ablow tae log in as anither uiser.",
 'createacct-emailoptional' => 'Wab-mail address (optional)',
 'createacct-email-ph' => 'Enter yer wab-mail address',
 'createacct-another-email-ph' => 'Enter wab-mail address',
-'createaccountmail' => 'Uise ae temporarie random password an send it til the speceefied wab-mail address',
+'createaccountmail' => 'Uise ae temporarie random passwaird n send it til the speceefied wab-mail address',
 'createacct-realname' => 'Real name (optional).',
 'createaccountreason' => 'Raison:',
 'createacct-reason' => 'Raison',
@@ -592,7 +594,7 @@ Tae finish loggin in, ye maun set ae new passwaird here:',
 'resetpass-temp-password' => 'Temperie passwaird:',
 'resetpass-abort-generic' => 'Passwaird chynge haes been aborted bi aen extension.',
 'resetpass-expired' => 'Yer passwaird haes expired. Please set ae new passwaird tae log-in.',
-'resetpass-expired-soft' => 'Yer passwaird haes expired, an needs tae be reset. Please chuise ae new passwaird nou, or clap oan cancel tae reset it later.',
+'resetpass-expired-soft' => 'Yer passwaird haes expired n needs tae be reset. Please chuise ae new passwaird nou, or clap oan "{{int:resetpass-submit-cancel}}" tae reset it later.',
 
 # Special:PasswordReset
 'passwordreset' => 'Reset passwaird',
@@ -663,7 +665,7 @@ Ye shid dae it gif ye accidentally shaired theim wi somebodie or gif yer accoont
 'link_sample' => 'Airtin teitle',
 'link_tip' => 'Internal airtin',
 'extlink_sample' => 'http://www.example.com airtin teitle',
-'extlink_tip' => 'Airtin tae an outby steid (mynd the http:// prefix)',
+'extlink_tip' => 'External link (mynd the http:// prefix)',
 'headline_sample' => 'Heidline tex',
 'headline_tip' => 'Level 2 heidline',
 'nowiki_sample' => 'Insert non-formattit tex here',
@@ -685,7 +687,7 @@ Ye shid dae it gif ye accidentally shaired theim wi somebodie or gif yer accoont
 'showpreview' => 'Scance ower',
 'showlivepreview' => 'Live leuk ower',
 'showdiff' => 'Shaw chynges',
-'anoneditwarning' => "<strong>Warnishment:</strong>Ye'r no loggit in. Yer IP address will be recordit in this page's eidit histerie.",
+'anoneditwarning' => "<strong>Warnishment:</strong>Ye'r no loggit in. Yer IP address will be recordit in this page's eedit histerie.",
 'anonpreviewwarning' => "<em>Ye'r no loggit in. hainin will record yer IP address in this page's eidit history.</em>",
 'missingsummary' => '<strong>Mynd:</strong> Ye\'v no gien aen eidit owerview. Gin ye dab oan "{{int:savearticle}}" again, yer eidit will be haint wioot ane.',
 'missingcommenttext' => 'Please enter a comment ablo.',
@@ -775,8 +777,8 @@ It's no been hained yet!</strong>",
 Yer chynges hae no been hained yet!',
 'continue-editing' => 'Gae til eiditing area',
 'previewconflict' => 'This scance reflects the tex in the upper tex eiditin area like it will kythe gin ye chuise tae hain.',
-'session_fail_preview' => "<strong>Sairy! We culdnae process yer eidit acause o ae loss o term data.</strong>
-Please try again. Gin it disnae wairk still, try loggin oot an loggin in again.'''",
+'session_fail_preview' => '<strong>Sairy! We culdnae process yer eidit acause o ae loss o term data.</strong>
+Please try again. Gin it disnae wairk still, try [[Secial:UserLogout|logging out]] an loggin in again.',
 'session_fail_preview_html' => "<strong>Sairrie! We coudna process yer eidit cause o ae loss o session data.</strong>
 
 <em>Cause {{SITENAME}} haes raw HTML enabled, the preview is skauk't aes ae precaution again JavaScript attacks.</em>
@@ -842,13 +844,13 @@ The delytion an muiv log fer this page is providit here:",
 'moveddeleted-notice' => 'This page haes bin delytit. 
 The delytion an muiv log fer the page ar provided ablo fer reference.',
 'log-fulllog' => 'View ful log',
-'edit-hook-aborted' => 'Eidit aborted bi huik.
+'edit-hook-aborted' => 'Eedit abortit bi huik.
 It gae naw explanation.',
 'edit-gone-missing' => 'Coudna update the page.
 It appears tae hae been deletit.',
-'edit-conflict' => 'Eidit conflict.',
-'edit-no-change' => 'Yer eidit wis ignored cause nae chynge wis made til the tex.',
-'postedit-confirmation' => 'Yer eidit wis hained.',
+'edit-conflict' => 'Eedit confleect.',
+'edit-no-change' => 'Yer eedit wis ignored cause nae chynge wis made til the tex.',
+'postedit-confirmation' => 'Yer eedit wis hained.',
 'edit-already-exists' => 'Coudna mak ae new page.
 It awreadie exists.',
 'defaultmessagetext' => 'Defaut message tex',
@@ -905,7 +907,7 @@ The raison gien bi $3 is ''$2''",
 
 # History pages
 'viewpagelogs' => 'Leuk at logs fer this page',
-'nohistory' => "Thaur's nae eidit histerie fer this page.",
+'nohistory' => "Thaur's nae eedit histerie fer this page.",
 'currentrev' => 'Current reveision',
 'currentrev-asof' => 'Latest reveesion aes o $1',
 'revisionasof' => 'Reveision as o $1',
@@ -954,16 +956,18 @@ Ye can view it; details can be foond in the [{{fullurl:{{#Special:Log}}/delete|p
 Ye can view it; details can be foond in the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].',
 'rev-deleted-no-diff' => 'Ye canna view this diff cause yin o the reveesions haes been <strong>delytit</strong>.
 Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].',
-'rev-suppressed-no-diff' => 'Ye cannae view this diff cause yin o the revisions haes been <strong>deletit</strong>.',
+'rev-suppressed-no-diff' => 'Ye cannae see this diff cause yin o the reveesions haes been <strong>delytit</strong>.',
 'rev-deleted-unhide-diff' => 'Yin o the reveesions o this diff haes been <strong>delytit</strong>.
 Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].
 Ye can still [$1 view this diff] gif ye wish tae proceed.',
 'rev-suppressed-unhide-diff' => 'Yin o the reveesions o this diff haes been <strong>suppressed</strong>.
 Details can be foond in the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].
 Ye can still [$1 view this diff] gif ye wish tee proceed.',
-'rev-suppressed-diff-view' => 'Yin o the revisions o this diff haes been <strong>suppressed</strong>.
+'rev-deleted-diff-view' => "Ane o the reveesions o this diff haes been '''delytit'''.
+Ye can see this diff; details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} delytion log].",
+'rev-suppressed-diff-view' => 'Yin o the reveesions o this diff haes been <strong>suppressed</strong>.
 Ye can view this diff; details can be foond in the [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} suppression log].',
-'rev-delundel' => 'shaw/scug',
+'rev-delundel' => 'chynge veesibility',
 'rev-showdeleted' => 'shaw',
 'revisiondelete' => 'Delyte/ondelyte reveesions',
 'revdelete-nooldid-title' => 'Onvalid target reveesion',
@@ -972,6 +976,7 @@ Ye can view this diff; details can be foond in the [{{fullurl:{{#Special:Log}}/s
 'revdelete-show-file-confirm' => 'Ar ye sair ye wish tae view ae deletit reveesion o the file "<nowiki>$1</nowiki>" fae $2 at $3?',
 'revdelete-show-file-submit' => 'Ai',
 'revdelete-selected' => '<strong>{{PLURAL:$2|Selected reveesion|Selected reveesions}} o [[:$1]]:</strong>',
+'logdelete-selected' => "'''{{PLURAL:$1|Selectit log event|Selectit log events}}:'''",
 'revdelete-text' => "<strong>Delytit reveesions an events will still kyth in the page histerie an logs, but pairts o their content will be onaccessible til the public.</strong>
 Ither admeenistraters oan {{SITENAME}} will still be able tae access the skauk't content an can ondelyte it again through this same interface, onless addeetional restreections ar set.",
 'revdelete-confirm' => "Please confirm that ye'r ettlin tae dae this, that ye unnerstaunn the consequences, an that ye'r daein this in accordance wi [[{{MediaWiki:Policy-url}}|the policie]].",
@@ -984,11 +989,11 @@ Ither admeenistraters oan {{SITENAME}} will still be able tae access the skauk't
 'revdelete-hide-image' => 'Skauk file content.',
 'revdelete-hide-name' => 'Skauk aiction an target',
 'revdelete-hide-comment' => 'Eidit summarie',
-'revdelete-hide-user' => "Eiditor's uisername/IP address",
+'revdelete-hide-user' => "Eiditer's uisername/IP address",
 'revdelete-hide-restricted' => 'Suppress data fae admeenistraters aes weel aes ithers',
 'revdelete-radio-same' => '(dinna chynge)',
 'revdelete-radio-set' => "Skauk't",
-'revdelete-radio-unset' => 'Visible',
+'revdelete-radio-unset' => 'Veesible',
 'revdelete-suppress' => 'Suppress data fae admeenistraters aes weel aes ithers',
 'revdelete-unsuppress' => 'Remuiv restreections oan restored reveesions',
 'revdelete-log' => 'Raison:',
@@ -1009,7 +1014,7 @@ Ye dinna hae access til it.',
 'revdelete-modify-no-access' => 'Mistak modifiein the eitem dated $2, $1: This eitem haes been maurked "restreected".
 Ye dinna hae access til it.',
 'revdelete-modify-missing' => 'Mistak modifiein item ID $1: It is missing fae the database!',
-'revdelete-no-change' => '<strong>Warnishment:</strong> The eitem dated $2, $1 awreadie haed the requested veesibeelitie settins.',
+'revdelete-no-change' => '<strong>Warnishment:</strong> The eetem dated $2, $1 awreadie haed the requested veesibeelitie settins.',
 'revdelete-concurrent-change' => "Mistak modifiein the eitem dated $2, $1: Its status appears tae'v been chynged bi some ither bodie while ye attempted tae modifie it.
 Please check the logs.",
 'revdelete-only-restricted' => 'Mistak hidin the item dated $2, $1: Ye canna suppress eitems fae view bi admeenistraters wioot selectin yin o the ither veesibeelitie opties ava.',
@@ -1035,15 +1040,15 @@ Mak sair that this chynge will maintain historical page conteenuitie.',
 'mergehistory-box' => 'Merge reveesions o twa pages:',
 'mergehistory-from' => 'Soorce page:',
 'mergehistory-into' => 'Destinâtion page:',
-'mergehistory-list' => 'Mergeable eidit history',
-'mergehistory-merge' => 'The follaein revisions o [[:$1]] can be merged intil [[:$2]].
-Uise the radio button column tae merge in yinly the reveesions maed at an afore the speecified time.
-Note that uising the navigâtion links will reset this column.',
+'mergehistory-list' => 'Mergeable eidit histerie',
+'mergehistory-merge' => 'The follaein reveesions o [[:$1]] can be merged intil [[:$2]].
+Uise the radio button column tae merge in yinly the reveesions makit at n afore the speecified time.
+Mynd that uisin the navigâtion links will reset this column.',
 'mergehistory-go' => 'Shaw mergeable eidits',
 'mergehistory-submit' => 'Merge reveesions',
 'mergehistory-empty' => 'Naw reveesions can be merged.',
 'mergehistory-success' => '$3 {{PLURAL:$3|reveesion|reveesions}} o [[:$1]] successfully merged intil [[:$2]].',
-'mergehistory-fail' => 'Onable tae perform histerie merge, please recheck the page an time parameters.',
+'mergehistory-fail' => 'Onable tae perform histerie merge, please recheck the page n time parameters.',
 'mergehistory-no-source' => 'Source page $1 disna exist.',
 'mergehistory-no-destination' => 'Destinâtion page $1 disna exist.',
 'mergehistory-invalid-source' => 'Source page maun be ae valid title.',
@@ -1062,7 +1067,7 @@ Note that uising the navigâtion links will reset this column.',
 # Diffs
 'history-title' => 'Reveesion histerie o "$1"',
 'difference-title' => 'Difference atween reveesions of "$1"',
-'difference-title-multipage' => 'Difference atween pages "$1" an "$2"',
+'difference-title-multipage' => 'Difference atween pages "$1" n "$2"',
 'difference-multipage' => '(Difference atween pages)',
 'lineno' => 'Line $1:',
 'compareselectedversions' => 'Compare selectit versions',
@@ -1093,7 +1098,7 @@ Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'searchmenu-exists' => "'''There is a page named \"[[:\$1]]\" oan this wiki.'''",
 'searchmenu-new' => '<strong>Mak the page "[[:$1]]" oan this wiki!</strong> {{PLURAL:$2|0=|See the page foond wi yer rake ava.|See the rake affcome foond ava.}}',
 'searchprofile-articles' => 'Content pages',
-'searchprofile-project' => 'Help and Project pages',
+'searchprofile-project' => 'Heelp n Waurk pages',
 'searchprofile-images' => 'Multimedia',
 'searchprofile-everything' => 'Everything',
 'searchprofile-advanced' => 'Advanced',
@@ -1140,7 +1145,7 @@ Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'skin-preview' => 'First Leuk',
 'datedefault' => 'Nae preference',
 'prefs-beta' => 'Beta features.',
-'prefs-datetime' => 'Date an time',
+'prefs-datetime' => 'Date n time',
 'prefs-labs' => 'Labs featurs',
 'prefs-user-pages' => 'Uiser pages',
 'prefs-personal' => 'Uiser data',
@@ -1153,21 +1158,37 @@ Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'prefs-watchlist-token' => 'Watchleet token:',
 'prefs-misc' => 'Antrin settins',
 'prefs-resetpass' => 'Chynge passwaird',
+'prefs-changeemail' => 'Chynge email address',
 'saveprefs' => 'Hain preferences',
+'restoreprefs' => 'Restore aw default settings (in aw sections)',
 'prefs-editing' => 'Editin',
 'searchresultshead' => 'Rake result settins',
+'stub-threshold' => 'Threshold for <a href="#" class="stub">stub link</a> formattin (bytes):',
 'stub-threshold-disabled' => 'Tuckie',
+'recentchangesdays' => 'Days tae shaw in recent chynges:',
 'recentchangescount' => 'Nummer o eidits tae shaw bi defaut:',
+'prefs-help-recentchangescount' => 'This includes recent chynges, page histories, n logs.',
 'prefs-help-watchlist-token2' => 'This is the hidlins key til the wab feed o yer watchleet. Onibodie wha kens this can read yer watchleet, sae dinna shair it. Gif ye need to, [[Special:ResetTokens|Ye can reset it]].',
 'savedprefs' => 'Yer preferences haes been hained.',
+'timezoneuseserverdefault' => 'Uise wiki default ($1)',
+'timezoneuseoffset' => 'Ither (specify offset)',
 'servertime' => 'Server time the nou',
 'guesstimezone' => 'Fill in frae brouser',
+'timezoneregion-africa' => 'Africae',
+'timezoneregion-america' => 'Americae',
+'timezoneregion-asia' => 'Asie',
+'timezoneregion-australia' => 'Australie',
+'timezoneregion-pacific' => 'Paceefic Ocean',
 'allowemail' => 'Allou email frae ither uisers',
+'prefs-searchoptions' => 'Rake',
 'defaultns' => 'Itherwise rake in thir namespaces:',
 'default' => 'defaut',
 'prefs-files' => 'Files',
 'prefs-custom-css' => 'Custom CSS',
 'prefs-custom-js' => 'Custom JS',
+'prefs-common-css-js' => 'Shared CSS/JavaScript for aw skins:',
+'prefs-reset-intro' => 'Ye can uise this page tae reset yer preferences tae the steid defaults.
+This cannae be unduin.',
 'youremail' => 'Yer email:',
 'username' => '{{GENDER:$1|Uisername}}:',
 'uid' => '{{GENDER:$1|Uiser}} ID:',
@@ -1175,34 +1196,88 @@ Details can be foond in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'yourrealname' => 'Yer real name:',
 'yourlanguage' => 'Interface leid:',
 'yourvariant' => 'Content leid variant',
+'prefs-help-variant' => 'Yer preferred variant or orthography tae display the content pages o this wiki in.',
 'yournick' => 'New seegnatur:',
+'prefs-help-signature' => 'Comments on collogue pages should be signed wi "<nowiki>~~~~</nowiki>", which will be convertit intae yer signatur an a timestamp.',
 'badsig' => 'Raw signature nae guid; check HTML tags.',
 'badsiglength' => 'Yer nickname is ower lang; it haes tae be $1 {{PLURAL:$1|character|characters}} or less.',
+'yourgender' => 'Hou dae ye prefer tae be describit?',
+'gender-unknown' => 'I prefer nae tae say',
+'prefs-help-gender' => 'Settin this preference is optional.
+The saftware uises its value tae address ye an tae mention ye tae ithers uisin the appropriate grammatical gender.
+This information will be public.',
 'email' => 'E-mail',
 'prefs-help-realname' => 'Rael name is optional an gin ye chuise tae provide it this will be uised tae gie ye attreibution for yer wark.',
 'prefs-help-email' => 'Wab-mail is optional, bit is needed fer passwaird resets, shid ye ferget yer passwaird.',
 'prefs-help-email-others' => 'Ye can chuise tae let ithers contact ye bi wab-mail through ae link oan yer uiser or tauk page.
 Yer wab-mail address isna revealed whan ither uisers contact ye.',
 'prefs-help-email-required' => 'Yer e-mail address is needit.',
+'prefs-i18n' => 'Internaitionalisation',
+'prefs-signature' => 'Signatur',
 'prefs-diffs' => 'Diffs',
+'prefs-help-prefershttps' => 'This preference will tak effect on yer next login.',
 
 # User rights
+'userrights' => 'Uiser richts management',
 'userrights-lookup-user' => 'Manish uiser boorachs',
 'userrights-user-editname' => 'Enter a uisername:',
 'editusergroup' => 'Eidit uiser boorach',
 'editinguser' => 'Chynging uiser richts o uiser <strong>[[User:$1|$1]]</strong> $2',
+'userrights-editusergroup' => 'Edit uiser groups',
+'saveusergroups' => 'Save uiser groups',
 'userrights-groupsmember' => 'Member o:',
+'userrights-groupsmember-auto' => 'Implicit member o:',
+'userrights-groups-help' => 'You mey alter the groups this uiser is in:
+* A checked box means the uiser is in that group.
+* An unchecked box means the uiser is nae in that group.
+* A * indicates that ye cannae remove the group ance you hae addit it, or vice versa.',
+'userrights-no-interwiki' => 'Ye dae nae hae permission tae edit uiser richts on ither wikis.',
+'userrights-nodatabase' => 'Database $1 daes nae exist or is nae local.',
+'userrights-nologin' => 'Ye maun [[Special:UserLogin|log in]] wi aen admeenistrater accoont tae assign uiser richts.',
+'userrights-notallowed' => 'Ye dae nae hae permission tae add or remove uiser richts.',
+'userrights-changeable-col' => 'Groups ye can chynge',
+'userrights-unchangeable-col' => 'Groups ye cannae chynge',
+'userrights-conflict' => 'Conflict o uiser richts chynges! Please luikower n confirm yer chynges.',
+'userrights-removed-self' => 'Ye successfully removed yer ain richts. As such, ye are no langer able tae access this page.',
 
 # Groups
 'group-user' => 'Uisers',
+'group-autoconfirmed' => 'Autoconfirmed uisers',
 'group-bot' => 'Bots',
+'group-sysop' => 'Admeenistrators',
+'group-suppress' => 'Owersichts',
 'group-all' => '(aw)',
 
 'group-user-member' => '{{GENDER:$1|uiser}}',
 'group-bot-member' => '{{GENDER:$1|bot}}',
 
 # Rights
+'right-createpage' => 'Create pages (which are nae discussion pages)',
+'right-createaccount' => 'Create new uiser accoonts',
+'right-minoredit' => 'Mark edits as smaa',
+'right-move' => 'Flit pages',
+'right-move-subpages' => 'Flit pages wi thair subpages',
+'right-move-rootuserpages' => 'Flit ruit uiser pages',
+'right-movefile' => 'Flit files',
+'right-suppressredirect' => 'Nae create redirects frae soorce pages when flittin pages',
+'right-upload' => 'Uplaid files',
+'right-reupload' => 'Owerwrite existin files',
+'right-reupload-own' => 'Owerwrite existin files uplaidit bi anesel',
+'right-reupload-shared' => 'Owerride files on the shared media repository locally',
+'right-upload_by_url' => 'Uplaid files frae a URL',
+'right-purge' => 'Purge the steid cache for a page wioot confirmation',
+'right-autoconfirmed' => 'Nae be affectit bi IP-based rate leemits',
+'right-bot' => 'Be treatit aes aen autæmatit process',
+'right-nominornewtalk' => 'Nae hae smaa edits tae discussion pages trigger the new messages prompt',
+'right-apihighlimits' => 'Uise heicher leemits in API queries',
+'right-writeapi' => 'Uise o the write API',
 'right-delete' => 'Delyte pages',
+'right-bigdelete' => 'Delete pages wi lairge histories',
+'right-deletelogentry' => 'Delyte n ondelyte speceefic log entries',
+'right-deleterevision' => 'Delyte n ondylete speceefic reveesions o pages',
+'right-deletedhistory' => 'View deletit history entries, wioot thair associatit text',
+'right-deletedtext' => 'See delytit tex n chynges atween delytit reveesions',
+'right-browsearchive' => 'Rake deletit pages',
 
 # Special:Log/newusers
 'newuserlogpage' => 'Uiser cræftin log',
@@ -1222,9 +1297,9 @@ Yer wab-mail address isna revealed whan ither uisers contact ye.',
 'recentchanges-feed-description' => 'Follae the maist recent chynges tae the wiki in this feed.',
 'recentchanges-label-newpage' => 'This edit created a freish page',
 'recentchanges-label-minor' => 'This is ae smaa eidit',
-'recentchanges-label-bot' => 'This edit wis performed by a bot',
+'recentchanges-label-bot' => 'This edit wis performed bi a bot',
 'recentchanges-label-unpatrolled' => 'This edit haes nae yet bin patrolled',
-'rcnotefrom' => 'Ablo is the chynges sin <strong>$2</strong> (up til <strong>$1</strong> shawn).',
+'rcnotefrom' => 'Ablo ar the chynges sin <strong>$2</strong> (up til <strong>$1</strong> shawn).',
 'rclistfrom' => 'Shaw new chynges stertin frae $1',
 'rcshowhideminor' => '$1 smaa edits',
 'rcshowhideminor-show' => 'Shaw',
@@ -1295,8 +1370,8 @@ Tae inclæde ae file in ae page, uise ae link in yin o the follaein forms:
 'largefileserver' => 'This file is bigger nor the server is confeigurt tae allou.',
 'fileexists' => "A file wi this name exists aareadies, please check <strong>[[:$1]]</strong> gin ye'r no siccar that ye want tae chynge it.
 [[$1|thumb]]",
-'fileexists-forbidden' => 'Ae file wi this name awreadie exists, an canna be owerwritten.
-Gif ye still wish tae uplaid yer file, please gae back an uise ae new name.
+'fileexists-forbidden' => 'Ae file wi this name awreadie exists, n canna be owerwritten.
+Gif ye still wish tae uplaid yer file, please gang back n uise ae new name.
 [[File:$1|thumb|center|$1]]',
 'fileexists-shared-forbidden' => 'Ae file wi this name awreadie exists in the shaired file repository.
 Gif ye still wish tae uplaid yer file, please gae back an uise ae new name.
@@ -1376,7 +1451,7 @@ Ilka rou contains airtins til the first and seicont redirect, aes weel aes the t
 
 'brokenredirects' => 'Brucken reguidals',
 'brokenredirectstext' => 'The folling redirects link til non-existent pages:',
-'brokenredirects-edit' => 'eidit',
+'brokenredirects-edit' => 'eedit',
 'brokenredirects-delete' => 'delyte',
 
 'withoutinterwiki' => 'Pages athoot leid links',
@@ -1465,7 +1540,7 @@ See [[Special:WantedCategories|wanted categories]] ava.',
 'special-categories-sort-abc' => 'sairt by the alphabet',
 
 # Special:DeletedContributions
-'sp-deletedcontributions-contribs' => 'contreibutions',
+'sp-deletedcontributions-contribs' => 'contreebutions',
 
 # Special:LinkSearch
 'linksearch-ns' => 'Namespace:',
@@ -1520,12 +1595,12 @@ Future chynges til this page an its associated tauk page will be leeted there.',
 # Delete
 'deletepage' => 'Delyte page',
 'excontent' => "content wis: '$1'",
-'excontentauthor' => "content wis: '$1' (an the ae contreibutor wis '[[Special:Contributions/$2|$2]]')",
+'excontentauthor' => "content wis: '$1' (n the ae contreebuter wis '[[Special:Contributions/$2|$2]]')",
 'exbeforeblank' => "content afore blankin wis: '$1'",
 'exblank' => 'page wis tuim',
 'delete-confirm' => 'Delyte "$1"',
 'delete-legend' => 'Delyte',
-'historywarning' => "<strong>Warnishment:</strong> The page ye'r aboot tae delete haes ae histerie wi approximatelie $1 {{PLURAL:$1|reveesion|reveesions}}:",
+'historywarning' => "<strong>Warnishment:</strong> The page that ye'r aboot tae delyte haes ae histerie wi approximatelie $1 {{PLURAL:$1|reveesion|reveesions}}:",
 'confirmdeletetext' => "Ye'r aboot tae permanently delete a page or eimage alang wi aa its history frae the database.
 Please confirm that ye intend tae dae this, that ye unnerstaun the consequences,
 an that ye'r daein this in accord wi [[{{MediaWiki:Policy-url}}]].",
@@ -1538,6 +1613,7 @@ an that ye'r daein this in accord wi [[{{MediaWiki:Policy-url}}]].",
 'reverted' => 'Revertit tae aulder reveision',
 'deletecomment' => 'Raeson:',
 'deletereasonotherlist' => 'Ither raeson',
+'deleting-backlinks-warning' => "'''Warnishment:''' ither pages link til or transclude the page ye'r aboot tae delyte.",
 
 # Rollback
 'rollback' => 'Row back edits',
@@ -1562,7 +1638,7 @@ See the [[Special:ProtectedPages|protected pages leet]] fer the leet o currently
 'prot_1movedto2' => '[[$1]] flittit til [[$2]]',
 'protectcomment' => 'Raeson:',
 'protectexpiry' => 'Expires:',
-'protect-text' => "Ye can see an chynge the protection level here for the page '''$1'''.",
+'protect-text' => 'Ye can see n chynge the protection level here fer the page <strong>$1</strong>.',
 'protect-default' => 'Allow aw uisers',
 'protect-level-autoconfirmed' => 'Allou yinly autæconfirmed uisers',
 'protect-level-sysop' => 'Allou admeenistraters yinly',
@@ -1578,13 +1654,13 @@ See the [[Special:ProtectedPages|protected pages leet]] fer the leet o currently
 
 # Undelete
 'undelete' => 'Restore delyte page',
-'undeletepage' => 'View an restore delytit pages',
+'undeletepage' => 'See n restore delytit pages',
 'viewdeletedpage' => 'View delyte pages',
-'undeletepagetext' => 'The follaeing {{PLURAL:$1|page haes been deletit but is|$1 pages hae been deletit but ar}} still in the archive an can be restored.
-The archive micht be cleaned oot nou an then.',
-'undeleteextrahelp' => "In order tae restore the page's entire histerie, lea aw checkboxes onselected an clap on <strong><em>{{int:undeletebtn}}</em></strong>.
-Tae perform ae selective restoration, check the boxes corresponding til the revisions tae be restored, an clap on <strong><em>{{int:undeletebtn}}</em></strong>.",
-'undeletehistory' => 'Gif ye restore the page, aw revisions will be restored til the histerie.
+'undeletepagetext' => 'The follaein {{PLURAL:$1|page haes been delytit but is|$1 pages hae been delytit but ar}} still in the archive n can be restored.
+The archive micht be cleaned oot nou n than.',
+'undeleteextrahelp' => "In order tae restore the page's entire histerie, lea aw checkkists onselected n clap oan <strong><em>{{int:undeletebtn}}</em></strong>.
+Tae perform ae selecteeve restoration, check the kists correspondin til the reveesions tae be restored, n clap oan <strong><em>{{int:undeletebtn}}</em></strong>.",
+'undeletehistory' => 'Gif ye restore the page, aw reveesions will be restored til the histerie.
 Gif ae new page wi the same name haes been makit sin the delytion, the restored reveesions will kyth in the prior histerie.',
 'undeletehistorynoadmin' => 'This airticle haes been delytit. The raeson fer delytion is
 shawn in the owerview ablo, alang wi parteeculars o the uisers that haed eiditit this page afore it wis delytit. The actual tex o thir delytit reveesions is available tae admeenistraters juist.',
@@ -1604,22 +1680,23 @@ Consult the [[Special:Log/delete|delytion log]] fer ae record o recent delytions
 
 # Contributions
 'contributions' => '{{GENDER:$1|Uiser}} contributions',
-'contributions-title' => 'Uiser contreibutions fer $1',
-'mycontris' => 'Ma contreibutions',
+'contributions-title' => 'Uiser contreebutions fer $1',
+'mycontris' => 'Ma contreebutions',
 'contribsub2' => 'Fer {{GENDER:$3|$1}} ($2)',
 'nocontribs' => 'Nae chynges wis funnd matchin thir criteria.',
 'uctop' => '(current)',
-'month' => 'Frae month (an afore):',
-'year' => 'Frae year (an afore):',
+'month' => 'Fae month (n afore):',
+'year' => 'Fae year (n afore):',
 
-'sp-contributions-newbies' => "Shaw contreibutions o' freish accounts ainlie",
+'sp-contributions-newbies' => 'Shaw contreebutions o freish accoonts ainlie',
 'sp-contributions-blocklog' => 'block log',
 'sp-contributions-uploads' => 'uploads',
 'sp-contributions-logs' => 'logs',
 'sp-contributions-talk' => 'tauk',
 'sp-contributions-search' => 'Rake fer contreebutions',
+'sp-contributions-suppresslog' => 'suppressed uiser contreebutions',
 'sp-contributions-username' => 'IP address or uisername:',
-'sp-contributions-toponly' => 'Ainlie shaw edits that are latest revisions',
+'sp-contributions-toponly' => 'Ainlie shaw eedits that ar laitest reveesions',
 'sp-contributions-newonly' => 'Yinlie shaw eidits that ar page cræftins',
 'sp-contributions-submit' => 'Rake',
 
@@ -1656,8 +1733,8 @@ Consult the [[Special:Log/delete|delytion log]] fer ae record o recent delytions
 <br />See [[Special:BlockList|block leet]] tae review blocks.',
 'ipb-unblock-addr' => 'Unblock $1',
 'unblockip' => 'Unblock uiser',
-'unblockiptext' => 'Uise the form ablo tae restore screivin richts
-tae an afore-blockit IP address or uisername.',
+'unblockiptext' => 'Uise the form ablo tae restore screevin richts
+til aen afore-blockit IP address or uisername.',
 'ipblocklist' => 'Blockit uisers',
 'anononlyblock' => 'anon. juist',
 'createaccountblock' => 'accoont-makkin blockit',
@@ -1667,12 +1744,12 @@ tae an afore-blockit IP address or uisername.',
 'contribslink' => 'contreibs',
 'autoblocker' => 'Autaematicallie blockit sin yer IP address haes been uised recentlie bi "[[User:$1|$1]]". The raeson gien fer $1\'s block is "$2"',
 'blocklogpage' => 'Block log',
-'blocklogentry' => 'blockit [[$1]] wi an expiry time o $2 $3',
+'blocklogentry' => 'blockit [[$1]] wi aen expirie time o $2 $3',
 'blocklogtext' => 'This is ae log o uiser blockin an onblockin actions. Autaematically blockit IP addresses isna leetit. See the [[Special:BlockList|block leet]] fer the leet o bans and blocks oan nou.',
 'unblocklogentry' => 'unblockit $1',
 'block-log-flags-nocreate' => 'accoont-makkin blockit',
 'range_block_disabled' => 'The administrator abeility tae mak range blocks is disabled.',
-'proxyblockreason' => 'Yer IP address haes been blockit sith it is an open proxy. Please contact yer Internet service provider or tech support an inform them o this serious security problem.',
+'proxyblockreason' => "Yer IP address haes been blockit cause it's aen apen proxie. Please contact yer Internet service provider or tech support n inform them o this serious securitie problem.",
 'sorbsreason' => 'Yer IP address is leeted aes aen apen proxy in the DNSBL uised bi {{SITENAME}}.',
 'sorbs_create_account_reason' => 'Yer IP address is leeted aes aen apen proxy in the DNSBL uised bi {{SITENAME}}.
 Ye canna mak aen accoont.',
@@ -1681,8 +1758,8 @@ Ye canna mak aen accoont.',
 'unlockdb' => 'Lowse database',
 'lockdbtext' => "Lockin the database will suspend the abeelitie o aa uisers tae eidit pages, chynge thair preeferences, eidit thair watchleets, an ither things requirin chynges in the database. Please confirm that this is whit ye'r etlin tae dae, an that ye'll lowse the database whan yer maintenance is duin.",
 'unlockdbtext' => 'Lowsin the database will gie back the abeelitie fer aa uisers tae eidit pages, chynge their preeferences, eidit their watchleets, an ither things needin chynges in the database. Please confirm that this is whit ye ettle tae dae.',
-'lockconfirm' => 'Aye, A raellie want tae lock the database.',
-'unlockconfirm' => 'Aye, A raelly want tae lowse the database.',
+'lockconfirm' => 'Ai, Ah reellie want tae lock the database.',
+'unlockconfirm' => 'Ai, Ah reellie want tae lowse the database.',
 'locknoconfirm' => 'Ye didna tick the confirmâtion kist.',
 'lockdbsuccesssub' => 'Database lock fine',
 'unlockdbsuccesssub' => 'Database lowsed',
@@ -1722,7 +1799,7 @@ please be sair ye unnerstaun the consequences o this afore preceedin.",
 In thae cases, ye will hae tae muiv or merge the page manuallie gif ye sae desire.',
 'movearticle' => 'Flit page:',
 'moveuserpage-warning' => "<strong>Warnishment:</strong> Ye'r aboot tae muiv ae uiser page. Please tak tent that yinly the page will be muivd n the uiser will <em>no</em> be renamed.",
-'movenologintext' => 'Ye maun be a registert uiser an [[Special:UserLogin|loggit in]] tae flit a page.',
+'movenologintext' => 'Ye maun be a registert uiser n [[Special:UserLogin|loggit in]] tae muiv ae page.',
 'newtitle' => 'Tae new teitle',
 'movepagebtn' => 'Flit page',
 'pagemovedsub' => 'Flittin succeedit',
@@ -1739,7 +1816,7 @@ In thae cases, ye will hae tae muiv or merge the page manuallie gif ye sae desir
 The destination airticle "[[:$1]]" aareadies exists. Div ye want tae delyte it fer tae mak wey fer the muiv?',
 'delete_and_move_confirm' => 'Ai, delyte the page',
 'delete_and_move_reason' => 'Deletit fer tae mak way fer muiv fae "[[$1]]"',
-'selfmove' => 'Ootgaun an incomin teitles is the same; canna flit a page ower itsel.',
+'selfmove' => 'Ootgaun n incomin teitles ar the same; canna flit ae page ower itsel.',
 'protectedpagemovewarning' => '<strong>Warnishment:</strong> This page haes been protected sae that yinly uisers wi admeenistrater preevileges can muiv it.
 The latest log entry is provided ablo fer reference:',
 'semiprotectedpagemovewarning' => '<strong>Note:</strong> This page has been protected sae that yinly registered uisers can muiv it.
@@ -1779,8 +1856,8 @@ Hain it til yer computer an uplaid it here.',
 'importnotext' => 'Tuim or nae tex',
 'importsuccess' => 'Importit fine!',
 'importhistoryconflict' => 'Conflictin histerie reveesion exeests (micht hae importit this page afore)',
-'importnosources' => 'Nae transwiki import soorces haes been defined an direct history uplaids is disabled.',
-'import-nonewrevisions' => 'Nae revisions imported (aw were either awready present, or skipped cause o errors).',
+'importnosources' => 'Nae transwiki import soorces haes been defined n direct histerie uplaids is disabled.',
+'import-nonewrevisions' => 'Nae reveesions imported (aw were either awreadie present, or skipt cause o mistaks).',
 'import-error-bad-location' => 'Reveesion $2 uisin content model $3 canna be stored oan "$1" oan this wiki, syn that model isna supported oan that page.',
 
 # Tooltip help for the actions
@@ -1788,15 +1865,15 @@ Hain it til yer computer an uplaid it here.',
 'tooltip-pt-mytalk' => 'Yer tauk page',
 'tooltip-pt-preferences' => 'Ma preferences',
 'tooltip-pt-watchlist' => "Ae leet o pages ye'r moniterin fer chynges",
-'tooltip-pt-mycontris' => 'Leet o yer contreibutions',
+'tooltip-pt-mycontris' => 'Leet o yer contreebutions',
 'tooltip-pt-login' => "It's a guid idea tae log i, but ye dinna hae tae.",
 'tooltip-pt-logout' => 'Log oot',
 'tooltip-ca-talk' => 'Discussion aneat the content page',
-'tooltip-ca-edit' => 'Ye can eidit this page. Please uise the preview button afore Hainin',
-'tooltip-ca-addsection' => 'Start a new section',
+'tooltip-ca-edit' => 'Ye can eedit this page. Please uise the luikower button afore hainin',
+'tooltip-ca-addsection' => 'Stairt a new section',
 'tooltip-ca-viewsource' => 'This page is protectit.
 Ye can view its soorce',
-'tooltip-ca-history' => "Bygane revisions o' this page",
+'tooltip-ca-history' => 'Bygane reveesions o this page',
 'tooltip-ca-protect' => 'Fend this page',
 'tooltip-ca-delete' => 'Delyte this page',
 'tooltip-ca-move' => 'Flit this page',
@@ -1816,7 +1893,7 @@ Ye can view its soorce',
 'tooltip-t-whatlinkshere' => "List o' a' wiki pages that link 'ere",
 'tooltip-t-recentchangeslinked' => 'Recent changes in pages linked frae this page',
 'tooltip-feed-atom' => 'Atom feed fer this page',
-'tooltip-t-contributions' => "View this uiser's contreibutions",
+'tooltip-t-contributions' => "View this uiser's contreebutions",
 'tooltip-t-emailuser' => 'Send ae wab-mail til this uiser',
 'tooltip-t-upload' => 'Uplaid files',
 'tooltip-t-specialpages' => 'Leet o byordinar pages',
@@ -1825,7 +1902,7 @@ Ye can view its soorce',
 'tooltip-ca-nstab-main' => 'Leuk at content page',
 'tooltip-ca-nstab-user' => 'View the uiser page',
 'tooltip-ca-nstab-special' => "This is ae byordinair page, ye cannae eidit th' page itsel",
-'tooltip-ca-nstab-project' => 'View the project page',
+'tooltip-ca-nstab-project' => 'See the waurk page',
 'tooltip-ca-nstab-image' => 'View the file page',
 'tooltip-ca-nstab-template' => 'View the template',
 'tooltip-ca-nstab-category' => 'View the categerie page',
@@ -1835,8 +1912,8 @@ Ye can view its soorce',
 'tooltip-diff' => 'Shaw the chynges that ye makit til the tex.',
 'tooltip-compareselectedversions' => 'See the differs atween the twa selectit versions o this page.',
 'tooltip-watch' => 'Add this page tae yer watchleet',
-'tooltip-rollback' => '"Rowback" reverts eidit(s) til this page o th\' laist contreebuter in yin clap',
-'tooltip-undo' => '"Ondae" reverts this eidit n apens the eidit form in luikower mode. It permits addin ae raison in the owerview.',
+'tooltip-rollback' => '"Rowback" reverts eedit(s) til this page o the laist contreebuter in yin clap',
+'tooltip-undo' => '"Ondae" reverts this eedit n apens the eedit form in luikower mode. It permits addin ae raison in the owerview.',
 'tooltip-summary' => 'Enter ae short owerview',
 
 # Metadata
@@ -1873,7 +1950,7 @@ Dae <strong>NO</strong> ful this in!',
 
 # Media information
 'mediawarning' => '<strong>Warnishment:</strong> This file type micht contain maleecious code.
-Bi executing it, yer system micht be compromised.',
+Bi executin it, yer system micht be compromised.',
 'imagemaxsize' => 'Eimage size limit:<br /><em>(fer file description pages)</em>',
 'file-info-size' => '$1 × $2 pixels, file size: $3, MIME type: $4',
 'file-nohires' => 'Na higher resolution available.',
@@ -1943,7 +2020,7 @@ Please check yer wab-mail address fer onvalid chairacters.
 Mailer returned: $1',
 'confirmemail_invalid' => 'Confirmation code nae guid. The code haes mibbe expired.',
 'confirmemail_needlogin' => 'Please $1 fer tae confirm yer wab-mail address.',
-'confirmemail_success' => 'Yer e-mail address haes been confirmed. Ye can nou log in an enjoy the wiki.',
+'confirmemail_success' => 'Yer wab-mail address haes been confirmed. Ye can nou log in an enjoy the wiki.',
 'confirmemail_loggedin' => 'Yer e-mail address haes noo been confirmed.',
 'confirmemail_body' => 'Somebodie, maist likely ye, fae IP address $1,
 haes registered aen accoont "$2" wi this wab-mail address oan {{SITENAME}}.
@@ -1961,13 +2038,13 @@ $5
 This confirmation code will expire oan $4.',
 
 # Delete conflict
-'deletedwhileediting' => '<strong>Warnishment:</strong> This page wis delytit efter ye stairted eiditin!',
+'deletedwhileediting' => '<strong>Warnishment:</strong> This page wis delytit efter ye stairted eeditin!',
 'confirmrecreate' => 'Uiser [[User:$1|$1]] ([[User talk:$1|tauk]]) delytit this page efter ye stairted eiditin wi raison:
 : <em>$2</em>
 Please confirm that ye reallie want tae recræft this page.',
 
 # action=purge
-'confirm_purge_button' => 'Aye',
+'confirm_purge_button' => 'OK',
 'confirm-purge-top' => 'Clair the cache o this page?',
 
 # Multipage image navigation
@@ -2001,7 +2078,7 @@ Please confirm that ye reallie want tae recræft this page.',
 
 # Special:SpecialPages
 'specialpages' => 'Byordinar pages',
-'specialpages-group-users' => 'Uisers an richts',
+'specialpages-group-users' => 'Uisers n richts',
 'specialpages-group-pages' => 'leet o pages',
 
 # External image whitelist
@@ -2017,7 +2094,7 @@ Please confirm that ye reallie want tae recræft this page.',
 # Special:Tags
 'tag-filter' => '[[Special:Tags|Tag]] filter:',
 'tag-filter-submit' => 'Filter',
-'tags-edit' => 'eidit',
+'tags-edit' => 'eedit',
 
 # HTML forms
 'htmlform-selectorother-other' => 'Ither',
index e138234..d409c83 100644 (file)
@@ -2620,6 +2620,7 @@ Najnovejši vnos v dnevniku blokad je naveden spodaj:',
 'sp-contributions-blocked-notice-anon' => 'Ta IP-naslov je trenutno blokiran.
 Najnovejši vnos v dnevniku blokad je naveden spodaj:',
 'sp-contributions-search' => 'Išči prispevke',
+'sp-contributions-suppresslog' => 'zatrti uporabnikovi prispevki',
 'sp-contributions-username' => 'IP-naslov ali uporabniško ime:',
 'sp-contributions-toponly' => 'Prikaži samo vrhnje redakcije',
 'sp-contributions-newonly' => 'Prikaži samo urejanja, ki so ustvarila nove strani',
index e4c82b0..9a20472 100644 (file)
@@ -17,6 +17,7 @@
  * @author Ergon
  * @author Euriditi
  * @author FatosMorina
+ * @author GretaDoci
  * @author Kaganer
  * @author Marinari
  * @author Mdupont
@@ -735,6 +736,8 @@ Për të hyrë tërësisht duhet të vendosni një fjalëkalim të ri këtu:',
 'resetpass-submit-cancel' => 'Anulo',
 'resetpass-wrong-oldpass' => 'Fjalëkalimi momental ose i përkohshëm nuk është i vlefshëm. Ndoshta tanimë me sukses keni ndërruar fjalëkalimin, ose keni kërkuar fjalëkalim të përkohshëm.',
 'resetpass-temp-password' => 'Fjalëkalimi i përkohshëm:',
+'resetpass-expired' => 'Fjalëkalimin tuaj ka skaduar. Ju lutem vendosni një fjalëkalim të ri për të hyr.',
+'resetpass-expired-soft' => 'Fjalëkalimi juaj ka skaduar dhe duhet të rivendoset. Ju lutem zgjidhni një fjalëkalim të ri tani, ose klikoni "{{int:resetpass-submit-cancel}}" për ta rivendosur më vonë.',
 
 # Special:PasswordReset
 'passwordreset' => 'Ndrysho fjalkalimin',
@@ -2420,6 +2423,7 @@ Bllokimi i fundit është shfaqur më poshtë për referencë:',
 'sp-contributions-blocked-notice-anon' => 'Kjo adresë IP është e bllokuar aktualisht.
 Bllokimi i funditë është më poshtë për referencë:',
 'sp-contributions-search' => 'Kërko tek kontributet',
+'sp-contributions-suppresslog' => 'Anëtar me Kontribute të kufizuara',
 'sp-contributions-username' => 'IP Addresa ose Përdoruesi:',
 'sp-contributions-toponly' => 'Trego vetëm redaktimet që janë versionet më të fundit',
 'sp-contributions-submit' => 'Kërko',
index 244efe1..7492d73 100644 (file)
@@ -3084,6 +3084,7 @@ $1',
 'allmessages-prefix' => 'Филтрирај по префиксу:',
 'allmessages-language' => 'Језик:',
 'allmessages-filter-submit' => 'Иди',
+'allmessages-filter-translate' => 'Преведи',
 
 # Thumbnails
 'thumbnail-more' => 'Повећај',
index d1b9c2b..e6a37f5 100644 (file)
@@ -2919,6 +2919,7 @@ Posetite [https://www.mediawiki.org/wiki/Localisation Medijaviki lokalizaciju] i
 'allmessages-prefix' => 'Filtriraj po prefiksu:',
 'allmessages-language' => 'Jezik:',
 'allmessages-filter-submit' => 'Idi',
+'allmessages-filter-translate' => 'Prevedi',
 
 # Thumbnails
 'thumbnail-more' => 'Povećaj',
index c710c70..0bba5e0 100644 (file)
@@ -897,7 +897,7 @@ För att slutföra inloggningen måste du välja ett nytt lösenord här:',
 'resetpass-temp-password' => 'Tillfälligt lösenord:',
 'resetpass-abort-generic' => 'Lösenordsändring av har avbrutits av ett tillägg.',
 'resetpass-expired' => 'Ditt lösenord har gått ut. Var god välj ett nytt lösenord för att logga in.',
-'resetpass-expired-soft' => 'Ditt lösenord har gått ut och behöver återställas. Var god välj ett nytt lösenord nu eller klicka på avbryt för att återställa det senare.',
+'resetpass-expired-soft' => 'Ditt lösenord har gått ut och behöver återställas. Var god välj ett nytt lösenord nu eller klicka på "{{int:resetpass-submit-cancel}}" för att återställa det senare.',
 
 # Special:PasswordReset
 'passwordreset' => 'Återställ lösenord',
@@ -1750,7 +1750,7 @@ Om du väljer att ange ditt riktiga namn, kommer det att användas för att till
 'recentchanges-legend-heading' => "'''Teckenförklaring:'''",
 'recentchanges-legend-newpage' => '(se även [[Special:NewPages|listan över nya sidor]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Nedan visas ändringar sedan '''$2''' (upp till '''$1''' ändringar visas).",
+'rcnotefrom' => 'Nedan visas ändringar sedan <strong>$2</strong> (upp till <strong>$1</strong> ändringar visas).',
 'rclistfrom' => 'Visa ändringar från och med $1',
 'rcshowhideminor' => '$1 mindre ändringar',
 'rcshowhideminor-show' => 'Visa',
@@ -1897,6 +1897,7 @@ Du borde be någon som kan se undanhållen fildata att granska situationen innan
 'uploaddisabledtext' => 'Uppladdning av filer är avstängd.',
 'php-uploaddisabledtext' => 'PHP filuppladdningar är avaktiverade. Kolla inställningarna för file_uploads.',
 'uploadscripted' => 'Denna fil innehåller HTML eller script som felaktigt kan komma att tolkas av webbläsare.',
+'uploadscriptednamespace' => 'Denna SVG-fil innehåller den ogiltiga namnrymden "$1"',
 'uploadinvalidxml' => 'XML-koden i den uppladdade filen kunde inte tolkas.',
 'uploadvirus' => 'Filen innehåller virus! Detaljer: $1',
 'uploadjava' => 'Filen är en ZIP-fil som innehåller en Java .class fil.
@@ -2726,6 +2727,7 @@ Den senaste posten i blockeringsloggen visas nedan som referens:',
 'sp-contributions-search' => 'Sök efter användarbidrag',
 'sp-contributions-username' => 'IP-adress eller användarnamn:',
 'sp-contributions-toponly' => 'Visa endast aktuella sidversioner',
+'sp-contributions-newonly' => 'Visa endast redigeringar där sidor skapas',
 'sp-contributions-submit' => 'Sök',
 
 # What links here
index 9f41dbf..b4d1470 100644 (file)
@@ -605,6 +605,9 @@ $1',
 'suspicious-userlogout' => 'உங்கள் விடுபதிகை கோரிக்கை மறுக்கப்பட்டது ஏனென்றால் அது அறுபட்ட உலாவி அல்லது மாற்று இடைக்கிடங்கியால் அனுப்பப்பட்டுள்ளது.',
 'createacct-another-realname-tip' => 'உண்மையான பெயர் கட்டாயமற்றது.
 நீங்கள் இதை கொடுத்தால் உங்கள் ஆக்கங்களுக்கான உரிமையளிப்புகளின் போது இது பயன்படும்.',
+'pt-login' => 'புகுபதிகை',
+'pt-createaccount' => 'புதிய கணக்கை உருவாக்கவும்',
+'pt-userlogout' => 'விடுபதிகை',
 
 # Email sending
 'php-mail-error-unknown' => "PHP 's mail() செயல்பாட்டில் அறியப்படாத பிழை.",
@@ -613,7 +616,7 @@ $1',
 
 # Change password dialog
 'changepassword' => 'கடவுச்சொல்லை மாற்று',
-'resetpass_announce' => 'நà¯\80à®\99à¯\8dà®\95ளà¯\8d à®¤à®±à¯\8dà®\95ாலிà®\95 à®®à®¿à®©à¯\8dனà®\9eà¯\8dà®\9aலà¯\8d à®\95à¯\81றியà¯\80à®\9fà¯\8dà®\9fà¯\81à®\9fனà¯\8d à®ªà¯\81à®\95à¯\81பதிà®\95à¯\88 à®\9aà¯\86யà¯\8dதà¯\81ளà¯\8dளà¯\80à®°à¯\8dà®\95ளà¯\8d. à®ªà¯\81à®\95à¯\81பதிà®\95à¯\88யà¯\88 à®¨à®¿à®±à¯\88வà¯\81à®\9aà¯\8d à®\9aà¯\86யà¯\8dய à®ªà¯\81தியà®\95à¯\8d à®\95à®\9fவà¯\81à®\9aà¯\8d à®\9aà¯\8aலà¯\8dலà¯\8aனà¯\8dà®±à¯\88 à®\87à®\99à¯\8dà®\95à¯\87 à®¤à®\9fà¯\8dà®\9fà®\9aிà®\9fà¯\81à®\95:',
+'resetpass_announce' => 'பà¯\81à®\95à¯\81பதிà®\95à¯\88யà¯\88 à®¨à®¿à®±à¯\88வà¯\81à®\9aà¯\8d à®\9aà¯\86யà¯\8dய à®ªà¯\81தியà®\95à¯\8d à®\95à®\9fவà¯\81à®\9aà¯\8d à®\9aà¯\8aலà¯\8dலà¯\8aனà¯\8dà®±à¯\88 à®¤à¯\87à®°à¯\8dவà¯\81 à®\9aà¯\86யà¯\8dயவà¯\87ணà¯\8dà®\9fà¯\81à®®à¯\8d.',
 'resetpass_header' => 'கணக்கிற்கான கடவுச்சொல்லை மாற்றியமை',
 'oldpassword' => 'பழைய கடவுச்சொல்:',
 'newpassword' => 'புதிய கடவுச்சொல்:',
@@ -627,6 +630,7 @@ $1',
 'resetpass-wrong-oldpass' => 'செல்லுபடியற்ற தற்காலிகமான அல்லது நடப்புக் கடவுச்சொல்.
 உங்கள் கடவுச் சொல்லை நீங்கள் வெற்றிகரமாக மாற்றிவிட்டீர்கள் அல்லது புதிய தற்காலிகக் கடவுச்சொல்லைக் கோரியுள்ளீர்கள்.',
 'resetpass-temp-password' => 'தற்காலிக கடவுச்சொல்:',
+'resetpass-expired' => 'உங்கள் கடவுச்சொல் காலாவதியாகிவிட்டது. உள்நுழைய ஒரு புதிய கடவுச்சொல்லை தெரிவுசெய்யவும்.',
 
 # Special:PasswordReset
 'passwordreset' => 'கடவுச்சொல்லை மீட்டமை',
@@ -2270,6 +2274,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'இந்த IP முகவரி தற்போது தடுக்கப்பட்டுள்ளது.
 சமீபத்திய தடுப்பு குறிப்பேடு  கீழே குறிப்பிற்காக வழங்கப்பட்டுள்ளது :',
 'sp-contributions-search' => 'பங்களிப்புகளைத் தேடு',
+'sp-contributions-suppresslog' => 'பயனரின் நீக்கப்பட்ட பங்களிப்புகள்',
 'sp-contributions-username' => 'ஐ.பி. அல்லது பயனர் பெயர்:',
 'sp-contributions-toponly' => 'சமீபத்திய பரிசீலனைகளுக்குட்பட்ட  திருத்தங்களை மட்டும் காண்பி',
 'sp-contributions-submit' => 'தேடுக',
index 217ba19..373b89b 100644 (file)
@@ -304,7 +304,7 @@ $messages = array(
 'vector-action-delete' => 'తొలగించు',
 'vector-action-move' => 'తరలించు',
 'vector-action-protect' => 'సంరక్షించు',
-'vector-action-undelete' => 'తిరిà°\97à°¿ à°\9aà±\87à°°à±\8dà°\9aà±\81',
+'vector-action-undelete' => 'à°¤à±\8aà°²à°\97à°¿à°\82à°ªà±\81à°¨à±\81 à°°à°¦à±\8dà°¦à±\81à°\9aà±\86à°¯à±\8dయి',
 'vector-action-unprotect' => 'సంరక్షణను మార్చు',
 'vector-view-create' => 'సృష్టించు',
 'vector-view-edit' => 'సవరించు',
@@ -338,7 +338,7 @@ $messages = array(
 'delete' => 'తొలగించు',
 'deletethispage' => 'ఈ పేజీని తొలగించండి',
 'undeletethispage' => 'ఈ పేజీ తొలగింపును ఆపు',
-'undelete_short' => '{{PLURAL:$1|ఒక్క రచనను|$1 రచనలను}} పునఃస్థాపించు',
+'undelete_short' => '{{PLURAL:$1|ఒక్క రచన|$1 రచనల}} తొలగింపును రద్దుచెయ్యి',
 'viewdeleted_short' => '{{PLURAL:$1|తొలగించిన ఒక మార్పు|$1 తొలగించిన మార్పుల}}ను చూడండి',
 'protect' => 'సంరక్షించు',
 'protect_change' => 'మార్చు',
@@ -365,7 +365,7 @@ $messages = array(
 'viewtalkpage' => 'చర్చను చూడు',
 'otherlanguages' => 'ఇతర భాషలలో',
 'redirectedfrom' => '($1 నుండి మళ్ళించబడింది)',
-'redirectpagesub' => 'దారిమారà±\8dà°ªà±\81 à°ªà±\81à°\9f',
+'redirectpagesub' => 'దారిమారà±\8dà°ªà±\81 à°ªà±\87à°\9cà±\80',
 'lastmodifiedat' => 'ఈ పేజీలో చివరి మార్పు $1 న $2 కు జరిగింది.',
 'viewcount' => 'ఈ పేజీ {{PLURAL:$1|ఒక్క సారి|$1 సార్లు}} దర్శించబడింది.',
 'protectedpage' => 'సంరక్షణలోని పేజీ',
@@ -385,7 +385,7 @@ $1',
 'aboutsite' => '{{SITENAME}} గురించి',
 'aboutpage' => 'Project:గురించి',
 'copyright' => 'విషయం $1 కి లోబడి లభ్యం, వేరుగా పేర్కొంటే తప్ప.',
-'copyrightpage' => '{{ns:project}}:à°ªà±\8dà°°à°\9aà±\81à°°à°£ హక్కులు',
+'copyrightpage' => '{{ns:project}}:à°\95ాపà±\80హక్కులు',
 'currentevents' => 'వర్తమాన ఘటనలు',
 'currentevents-url' => 'Project:వర్తమాన ఘటనలు',
 'disclaimers' => 'అస్వీకారములు',
@@ -402,7 +402,7 @@ $1',
 
 'badaccess' => 'అనుమతి లోపం',
 'badaccess-group0' => 'మీరు చేయతలపెట్టిన పనికి మీకు హక్కులు లేవు.',
-'badaccess-groups' => 'మీరు చేయతలపెట్టిన పని ఈ {{PLURAL:$2|గుంపు|గుంపుల}} లోని వాడుకర్లకు మాత్రమే పరిమితం: $1.',
+'badaccess-groups' => 'మీరు చేయతలపెట్టిన పని ఈ {{PLURAL:$2|గుంపు|గుంపులలో ఒకదాని}} లోని వాడుకర్లకు మాత్రమే పరిమితం: $1.',
 
 'versionrequired' => 'మీడియావికీ సాఫ్టువేరు వెర్షను $1 కావాలి',
 'versionrequiredtext' => 'ఈ పేజీని వాడటానికి మీకు మీడియావికీ సాఫ్టువేరు వెర్షను $1 కావాలి. [[Special:Version|వెర్షను పేజీ]]ని చూడండి.',
@@ -502,24 +502,24 @@ $1',
 'badarticleerror' => 'ఈ పేజీపై ఈ పని చేయడం కుదరదు.',
 'cannotdelete' => '"$1" అనే పేజీ లేదా ఫైలుని తొలగించలేకపోయాం.
 దాన్ని ఇప్పటికే ఎవరైనా తొలగించి ఉండవచ్చు.',
-'cannotdelete-title' => '"$1" పుటను తొలగించలేరు',
+'cannotdelete-title' => 'పేజీ "$1" ని తొలగించలేరు',
 'delete-hook-aborted' => 'తొలగింపును హుక్ ఆపేసింది.
 వివరణ ఏమీ ఇవ్వలేదు.',
 'no-null-revision' => '"$1" పేజీకి కొత్త శూన్య కూర్పు (నల్ రివిజన్) ను సృష్టించలేకపోయాం',
 'badtitle' => 'తప్పు శీర్షిక',
-'badtitletext' => 'à°®à±\80à°°à±\81 à°\95à±\8bà°°à°¿à°¨ à°ªà±\81à°\9f à°¯à±\8aà°\95à±\8dà°\95 à°ªà±\87à°°à±\81 à°\9aà±\86à°²à±\8dలనిది, à°\96ాళà±\80à°\97à°¾ à°\89à°\82ది, à°²à±\87దా à°¤à°ªà±\8dà°ªà±\81à°\97à°¾ à°\87à°\9aà±\8dà°\9aిన అంతర్వికీ లేదా అంతర-భాషా శీర్షిక అయివుండాలి.
+'badtitletext' => 'à°®à±\80à°°à±\81 à°\95à±\8bà°°à°¿à°¨ à°ªà±\87à°\9cà±\80 à°¯à±\8aà°\95à±\8dà°\95 à°ªà±\87à°°à±\81 à°\9aà±\86à°²à±\8dలనిది, à°\96ాళà±\80à°\97à°¾ à°\89à°\82ది, à°²à±\87దా à°¤à°ªà±\8dà°ªà±\81 à°²à°¿à°\82à°\95à±\81à°¤à±\8b à°\95à±\82à°¡ిన అంతర్వికీ లేదా అంతర-భాషా శీర్షిక అయివుండాలి.
 శీర్షికలలో ఉపయోగించకూడని అక్షరాలు దానిలో ఉండివుండొచ్చు.',
 'perfcached' => 'కింది డేటా ముందే సేకరించి పెట్టుకున్నది. కాబట్టి తాజా డేటాతో పోలిస్తే తేడాలుండవచ్చు. ఈ కాషెలో గరిష్టంగా {{PLURAL:$1|ఒక్క ఫలితం ఉంది|$1 ఫలితాలు ఉన్నాయి}}.',
 'perfcachedts' => 'కింది సమాచారం ముందే సేకరించి పెట్టుకున్నది. దీన్ని $1న చివరిసారిగా తాజాకరించారు. ఈ కాషెలో గరిష్టంగా {{PLURAL:$4|ఒక్క ఫలితం ఉంది|$4 ఫలితాలు ఉన్నాయి}}.',
-'querypage-no-updates' => 'à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤à°\82 à°\88 à°ªà±\81à°\9fకి తాజాకరణలని అచేతనం చేసారు.
-à°\87à°\95à±\8dà°\95à°¡à±\81à°¨à±\8dà°¨ à°­à±\8bà°\97à°\9fà±\8dà°\9fà°¾ à°\95à±\82à°¡à°¾ తాజాకరించబడదు.',
+'querypage-no-updates' => 'à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤à°\82 à°\88 à°ªà±\87à°\9cà±\80కి తాజాకరణలని అచేతనం చేసారు.
+à°\87à°\95à±\8dà°\95à°¡à±\81à°¨à±\8dà°¨ à°¡à±\87à°\9fà°¾ à°\95à±\82à°¡à°¾ à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤à°\82 తాజాకరించబడదు.',
 'viewsource' => 'మూలాన్ని చూపించు',
 'viewsource-title' => '$1 యొక్క సోర్సు చూడండి',
 'actionthrottled' => 'కార్యాన్ని ఆపేసారు',
-'actionthrottledtext' => 'à°¸à±\8dపామà±\81à°¨à±\81 à°¤à°\97à±\8dà°\97à°¿à°\82à°\9aà°\9fానిà°\95à°¿ à°¤à±\80à°¸à±\81à°\95à±\81à°¨à±\8dà°¨ à°¨à°¿à°°à±\8dణయాల à°µà°²à±\8dà°², à°®à±\80à°°à±\81 à°\88 à°\95ారà±\8dయానà±\8dని à°\85తి à°¤à°\95à±\8dà°\95à±\81à°µ à°¸à°®à°¯à°\82à°²à±\8b à°¬à±\8bà°²à±\86à°¡à°¨à±\8dని à°¸à°¾à°°à±\8dà°²à±\81 à°\9aà±\87à°¯à°\95à±\81à°\82à°¡à°¾ à°\85à°¡à±\8dà°¡à±\81à°\95à±\81à°\82à°\9fà±\81à°¨à±\8dనాము. కొన్ని నిమిషాలు ఆగి మరలా ప్రయత్నించండి.',
+'actionthrottledtext' => 'à°¸à±\8dపామà±\81à°¨à±\81 à°¨à°¿à°°à±\8bధిà°\82à°\9aà±\87à°\82à°¦à±\81à°\95à±\81 à°\97ానà±\81, à°¤à°\95à±\8dà°\95à±\81à°µ à°¸à°®à°¯à°\82à°²à±\8b à°®à°°à±\80 à°\8eà°\95à±\8dà°\95à±\81à°µ à°¸à°¾à°°à±\8dà°²à±\81 à°\88 à°ªà°¨à°¿ à°\9aà±\87à°¯à°\95à±\81à°\82à°¡à°¾ à°ªà°°à°¿à°®à°¿à°¤à°¿ à°µà°¿à°§à°¿à°\82à°\9aà°¾à°\82. à°®à±\80à°°à±\81 à°¦à°¾à°¨à±\8dని à°\85ధిà°\97మిà°\82à°\9aారు. కొన్ని నిమిషాలు ఆగి మరలా ప్రయత్నించండి.',
 'protectedpagetext' => 'ఈ పేజీలో మార్పులు వగైరాలు చెయ్యకుండా ఉండేందుకు గాను, సంరక్షించబడింది.',
 'viewsourcetext' => 'మీరీ పేజీ సోర్సును చూడవచ్చు, కాపీ చేసుకోవచ్చు:',
-'viewyourtext' => "ఈ పేజీకి '''మీ మార్పుల''' యొక్క మూలాన్ని చూడవచ్చు లేదా కాపీచేసుకోవచ్చు:",
+'viewyourtext' => 'ఈ పేజీలోని <strong>మీ మార్పుల</strong> యొక్క మూలాన్ని చూడవచ్చు, కాపీచేసుకోవచ్చు:',
 'protectedinterface' => 'ఈ పేజీ, ఈ వికీ యొక్క సాఫ్టువేరు ఇంటరుఫేసుకు చెందిన టెక్స్టును అందిస్తుంది. దుశ్చర్యల నివారణ కోసమై దీన్ని సంరక్షించాం. వికీలన్నిటిలోను అనువాదాలను చేర్చాలన్నా, మార్చాలన్నా మీడియావికీ స్థానికీకరణ ప్రాజెక్టైన [//translatewiki.net/ translatewiki.net] ను వాడండి.',
 'editinginterface' => '<strong>హెచ్చరిక:</strong> సాఫ్టువేరుకు ఇంటరుఫేసు టెక్స్టును అందించేందుకు పనికొచ్చే పేజీని మీరు సరిదిద్దుతున్నారు.
 ఈ పేజీలో చేసే మార్పుల వల్ల ఇతర వాడుకరులకు ఇంటరుఫేసు కనబడే విధానంలో తేడావస్తుంది.
@@ -534,19 +534,19 @@ $2',
 'myprivateinfoprotected' => 'మీ అంతరంగిక సమాచారాన్ని సవరించేందుకు మీకు అనుమతి లేదు.',
 'mypreferencesprotected' => 'మీ అభీష్టాలను సవరించేందుకు మీకు అనుమతి లేదు.',
 'ns-specialprotected' => 'ప్రత్యేక పేజీలపై దిద్దుబాట్లు చేయలేరు.',
-'titleprotected' => "సభ్యులు [[User:$1|$1]] ఈ పేజీని సృష్టించనివ్వకుండా నిరోదిస్తున్నారు.
-అందుకు ఇచ్చిన కారణం: ''$2''.",
+'titleprotected' => '[[User:$1|$1]] ఈ శీర్షికని సృష్టించకుండా ఇది సంరక్షించబడింది.
+అందుకు ఇచ్చిన కారణం: "<em>$2</em>".',
 'filereadonlyerror' => 'ఫైలు ఖజానా "$2" రీడ్-ఓన్లీ స్థితిలో ఉండటం చేత "$1" ఫైలులో మార్పులు చెయ్యలేకపోయాం.
 
 దానికి తాళం వేసిన అధికారి ఇచ్చిన వివరణ ఇది: "$3".',
 'invalidtitle-knownnamespace' => 'పేరుబరి "$2", పాఠ్యము "$3" తో కూడిన ఈ శీర్షిక చెల్లనిది',
 'invalidtitle-unknownnamespace' => 'అపరిచితమైన పేరుబరి సంఖ్య "$1", పాఠ్యము "$2" తో కూడిన ఈ శీర్షిక చెల్లనిది',
-'exception-nologin' => 'à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿లేరు',
-'exception-nologin-text' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°\9aà±\82డడానిà°\95à°¿ à°²à±\87దా à°\88 à°\9aà°°à±\8dయనà±\81 à°\9aà±\86à°¯à±\8dయడానిà°\95à°¿ à°¦à°¯à°\9aà±\87సి [[Special:Userlogin|à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aండి]].',
+'exception-nologin' => 'లాà°\97à°¿à°¨à±\88 లేరు',
+'exception-nologin-text' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°\9aà±\82డడానిà°\95à°¿ à°²à±\87దా à°\88 à°ªà°¨à°¿ à°\9aà±\86à°¯à±\8dయడానిà°\95à°¿ [[Special:Userlogin|లాà°\97ినవండి]].',
 'exception-nologin-text-manual' => 'ఈ పేజీ చూసేందుకు లేదా ఈ పని చేసేందుకు $1.',
 
 # Virus scanner
-'virus-badscanner' => "తప్పుడు స్వరూపణం: తెలియని వైరస్ స్కానర్: ''$1''",
+'virus-badscanner' => 'తప్పుడు స్వరూపణం: తెలియని వైరస్ స్కానర్: <em>$1</em>',
 'virus-scanfailed' => 'స్కాన్ విఫలమైంది (సంకేతం $1)',
 'virus-unknownscanner' => 'అజ్ఞాత యాంటీవైరస్:',
 
@@ -564,7 +564,7 @@ $2',
 'yourname' => 'వాడుకరి పేరు:',
 'userlogin-yourname' => 'వాడుకరి పేరు',
 'userlogin-yourname-ph' => 'మీ వాడుకరి పేరును ఇవ్వండి',
-'createacct-another-username-ph' => 'à°®à±\80 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°ªà±\87à°°à±\81à°¨à±\81 à°ªà±\8dà°°à°µà±\87శపà±\86à°\9fà±\8dà°\9fండి',
+'createacct-another-username-ph' => 'à°®à±\80 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°ªà±\87à°°à±\81à°¨à±\81 à°\87à°µà±\8dà°µండి',
 'yourpassword' => 'సంకేతపదం:',
 'userlogin-yourpassword' => 'సంకేతపదం',
 'userlogin-yourpassword-ph' => 'మీ సంకేతపదాన్ని ఇవ్వండి',
@@ -573,30 +573,30 @@ $2',
 'createacct-yourpasswordagain' => 'సంకేతపదాన్ని నిర్ధారించండి',
 'createacct-yourpasswordagain-ph' => 'సంకేతపదాన్ని మళ్ళీ ఇవ్వండి',
 'remembermypassword' => 'ఈ కంప్యూటరులో నా ప్రవేశాన్ని గుర్తుంచుకో (గరిష్ఠంగా $1 {{PLURAL:$1|రోజు|రోజుల}}కి)',
-'userlogin-remembermypassword' => 'ననà±\8dà°¨à±\81 à°ªà±\8dà°°à°µà±\87శిà°\82à°ªà°\9cà±\87సి ఉంచు',
+'userlogin-remembermypassword' => 'ననà±\8dà°¨à±\81 à°²à°¾à°\97à°¿à°¨à±\8d à°\9aà±\87à°¸à±\87 ఉంచు',
 'userlogin-signwithsecure' => 'సురక్షిత కనెక్షను వాడు',
 'yourdomainname' => 'మీ డోమైను',
 'password-change-forbidden' => 'ఈ వికీలో మీరు సంకేతపదాలను మార్చలేరు.',
 'externaldberror' => 'డేటాబేసు అధీకరణలో లోపం జరిగింది లేదా మీ బయటి ఖాతాను తాజాకరించడానికి మీకు అనుమతి లేదు.',
-'login' => 'à°²à±\8bనిà°\95à°¿ à°°ండి',
+'login' => 'లాà°\97ినవండి',
 'nav-login-createaccount' => 'లాగినవండి / ఖాతాని సృష్టించుకోండి',
 'loginprompt' => '{{SITENAME}}లోకి ప్రవేశించాలంటే మీ విహారిణిలో కూకీలు చేతనమై ఉండాలి.',
-'userlogin' => 'à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aండి / ఖాతాను సృష్టించుకోండి',
-'userloginnocreate' => 'à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aండి',
+'userlogin' => 'లాà°\97ినవండి / ఖాతాను సృష్టించుకోండి',
+'userloginnocreate' => 'లాà°\97ినవండి',
 'logout' => 'నిష్క్రమించు',
 'userlogout' => 'లాగౌట్',
-'notloggedin' => 'à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿ లేరు',
+'notloggedin' => 'లాà°\97à°¿à°¨à±\8dâ\80\8c à°\85యిలేరు',
 'userlogin-noaccount' => 'మీకు ఖాతా లేదా?',
 'userlogin-joinproject' => '{{SITENAME}}లో చేరండి',
 'nologin' => 'ఖాతా లేదా? $1.',
 'nologinlink' => 'ఖాతాని సృష్టించుకోండి',
 'createaccount' => 'ఖాతాని సృష్టించు',
 'gotaccount' => 'ఇప్పటికే మీకు ఖాతా ఉందా? $1.',
-'gotaccountlink' => 'à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aండి',
-'userlogin-resetlink' => 'à°®à±\80 à°ªà±\8dà°°à°µà±\87à°¶ వివరాలను మరచిపోయారా?',
+'gotaccountlink' => 'లాà°\97ినవండి',
+'userlogin-resetlink' => 'à°®à±\80 à°²à°¾à°\97à°¿à°¨à±\8d వివరాలను మరచిపోయారా?',
 'userlogin-resetpassword-link' => 'మీ సంకేతపదాన్ని మర్చిపోయారా?',
-'helplogin-url' => 'Help:à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aడం',
-'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aడానిà°\95à°¿ సహాయం]]',
+'helplogin-url' => 'Help:లాà°\97ినవడం',
+'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|లాà°\97ినవడà°\82à°²à±\8b సహాయం]]',
 'userlogin-loggedin' => 'మీరు ఈసరికే {{GENDER:$1|$1}} గా లాగిన్ అయి ఉన్నారు.
 వేరే వాడుకరిగా లాగినయేందుకు కింది ఫారమును వాడండి.',
 'userlogin-createanother' => 'మరొక ఖాతాను సృష్టించండి',
@@ -652,23 +652,23 @@ $2',
 'passwordremindertitle' => '{{SITENAME}} కోసం కొత్త తాత్కాలిక సంకేతపదం',
 'passwordremindertext' => '{{SITENAME}} ($4) లో కొత్త సంకేతపదం పంపించమని ఎవరో (బహుశ మీరే, ఐ.పీ. చిరునామా $1 నుండి) అడిగారు. వాడుకరి "$2" కొరకు "$3" అనే తాత్కాలిక సంకేతపదం సిద్ధంచేసి ఉంచాం. మీ ఉద్దేశం అదే అయితే, ఇప్పుడు మీరు సైటులోనికి ప్రవేశించి కొత్త సంకేతపదాన్ని ఎంచుకోవచ్చు. మీ తాత్కాలిక సంకేతపదం {{PLURAL:$5|ఒక రోజు|$5 రోజుల}}లో కాలంచెల్లుతుంది.
 
-à°\92à°\95à°µà±\87à°³ à°\88 à°\85à°­à±\8dయరà±\8dథన à°®à±\80à°°à±\81à°\95à°¾à°\95 à°®à°°à±\86వరà±\8b à°\9aà±\87సారనà±\81à°\95à±\81à°¨à±\8dనా à°²à±\87దా à°®à±\80 à°¸à°\82à°\95à±\87తపదà°\82 à°®à±\80à°\95à±\81 à°\97à±\81à°°à±\8dà°¤à±\81à°\95à±\81à°µà°\9aà±\8dà°\9aà°¿ à°¦à°¾à°¨à±\8dని à°®à°¾à°°à±\8dà°\9aà°\95à±\82à°¡à°¦à±\81 à°\85à°¨à±\81à°\95à±\81à°\82à°\9fà±\81à°¨à±\8dనా, à°\88 à°¸à°\82à°¦à±\87శానà±\8dని à°®à°°à±\8dà°\9aà°¿à°ªà±\8bà°¯ి మీ పాత సంకేతపదాన్ని వాడడం కొనసాగించవచ్చు.',
-'noemail' => 'సభà±\8dà°¯à±\81à°²à±\81 "$1"à°\95à±\81 à°\88-మెయిలు చిరునామా నమోదయి లేదు.',
+à°\92à°\95à°µà±\87à°³ à°\88 à°\85à°­à±\8dయరà±\8dథన à°®à±\80à°°à±\81à°\95à°¾à°\95 à°®à°°à±\86వరà±\8b à°\9aà±\87సారనà±\81à°\95à±\81à°¨à±\8dనా à°²à±\87దా à°®à±\80 à°¸à°\82à°\95à±\87తపదà°\82 à°®à±\80à°\95à±\81 à°\97à±\81à°°à±\8dà°¤à±\81à°\95à±\81à°µà°\9aà±\8dà°\9aà°¿ à°¦à°¾à°¨à±\8dని à°®à°¾à°°à±\8dà°\9aà°\95à±\82à°¡à°¦à±\81 à°\85à°¨à±\81à°\95à±\81à°\82à°\9fà±\81à°¨à±\8dనా, à°\88 à°¸à°\82à°¦à±\87శానà±\8dని à°µà°¿à°¸à±\8dమరిà°\82à°\9aి మీ పాత సంకేతపదాన్ని వాడడం కొనసాగించవచ్చు.',
+'noemail' => 'వాడà±\81à°\95à°°à°¿ "$1" à°\95à±\81 à°\88మెయిలు చిరునామా నమోదయి లేదు.',
 'noemailcreate' => 'మీరు సరైన ఈమెయిల్ చిరునామాని ఇవ్వాలి',
 'passwordsent' => '"$1" కొరకు నమోదైన ఈ-మెయిలు చిరునామాకి కొత్త సంకేతపదాన్ని పంపించాం.
 అది అందిన తర్వాత ప్రవేశించి చూడండి.',
-'blocked-mailpassword' => 'దిదà±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\9aà±\86à°¯à±\8dà°¯à°\95à±\81à°\82à°¡à°¾ à°\88 à°\90à°ªà±\80à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81 à°¨à°¿à°°à±\8bధిà°\82à°\9aà°¾à°\82. à°\85à°\82à°\9aà±\87à°¤, à°¦à±\81à°¶à±\8dà°\9aà°°à±\8dయల à°¨à°¿à°µà°¾à°°à°£ à°\95à±\8bà°¸à°\82 à°\97ానà±\81, à°®à°°à°\9aà°¿à°ªà±\8bయిన à°¸à°\82à°\95à±\87తపదానà±\8dని à°ªà±\8aà°\82à°¦à±\87 à°\85à°\82శానà±\8dని à°\85à°¨à±\81మతిà°\82à°\9aà°®ు.',
+'blocked-mailpassword' => 'దిదà±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\9aà±\86à°¯à±\8dà°¯à°\95à±\81à°\82à°¡à°¾ à°®à±\80 à°\90à°ªà±\80à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81 à°¨à°¿à°°à±\8bధిà°\82à°\9aà°¾à°\82. à°\85à°\82à°\9aà±\87à°¤, à°¦à±\81à°¶à±\8dà°\9aà°°à±\8dయల à°¨à°¿à°µà°¾à°°à°£ à°\95à±\8bà°¸à°\82 à°\97ానà±\81, à°®à°°à°\9aà°¿à°ªà±\8bయిన à°¸à°\82à°\95à±\87తపదానà±\8dని à°ªà±\8aà°\82à°¦à±\87 à°µà±\80à°²à±\81 à°\88 à°\90à°ªà±\80à°\95à°¿ à°²à±\87à°¦ు.',
 'eauthentsent' => 'ఇచ్చిన ఈ-మెయిలు అడ్రసుకు ధృవీకరణ మెయిలు పంపించాం.
 ఇకపై మేము ఆ ఖాతాకు మెయిలు పంపాలంటే, ముందుగా మీరు ఆ మెయిల్లో సూచించినట్లుగా చేసి, ఈ చిరునామా మీదేనని ధృవీకరించాలి.',
-'throttled-mailpassword' => 'à°\97à°¡à°\9aà°¿à°¨ {{PLURAL:$1|à°\92à°\95 à°\97à°\82à°\9fà°²à±\8b|$1 à°\97à°\82à°\9fà°²à±\8dà°²à±\8b}} à°\87à°ªà±\8dà°ªà°\9fà°¿à°\95à±\87  à°¦à°¾à°\9fà±\81మాà°\9f à°®à°¾à°°à±\8dà°\9aà°¿à°¨à°\9fà±\8dà°²à±\81à°\97à°¾ à°\92à°\95 à°®à±\86యిలà±\8d  పంపించివున్నాం.
-à°¦à±\81à°¶à±\8dà°\9aà°°à±\8dయలనà±\81 à°¨à°¿à°µà°¾à°°à°¿à°\82à°\9aà±\87à°\82à°¦à±\81à°\95à±\81 à°\97ానà±\81, {{PLURAL:$1|à°\92à°\95 à°\97à°\82à°\9fà°\95à°¿|$1 à°\97à°\82à°\9fà°²à°\95à°¿}} à°\92à°\95à±\8dà°\95సారి à°®à°¾à°¤à±\8dà°°à°®à±\87 à°¦à°¾à°\9fà±\81మాà°\9f à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\86యిలà±\8d పంపిస్తాము.',
+'throttled-mailpassword' => 'à°\97à°¡à°\9aà°¿à°¨ {{PLURAL:$1|à°\92à°\95 à°\97à°\82à°\9fà°²à±\8b|$1 à°\97à°\82à°\9fà°²à±\8dà°²à±\8b}} à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°\9aà°¿à°¨à°\9fà±\8dà°²à±\81à°\97à°¾ à°\92à°\95 à°®à±\86యిలà±\81 పంపించివున్నాం.
+à°¦à±\81à°¶à±\8dà°\9aà°°à±\8dయలనà±\81 à°¨à°¿à°µà°¾à°°à°¿à°\82à°\9aà±\87à°\82à°¦à±\81à°\95à±\81 à°\97ానà±\81, {{PLURAL:$1|à°\92à°\95 à°\97à°\82à°\9fà°\95à±\81|$1 à°\97à°\82à°\9fà°²à°\95à±\81}} à°\92à°\95à±\8dà°\95సారి à°®à°¾à°¤à±\8dà°°à°®à±\87 à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°ªà±\81 à°®à±\86యిలà±\81 పంపిస్తాము.',
 'mailerror' => 'మెయిలు పంపించడంలో లోపం: $1',
 'acct_creation_throttle_hit' => 'మీ ఐపీ చిరునామా వాడుతున్న ఈ వికీ సందర్శకులు గత ఒక్క రోజులో {{PLURAL:$1|1 ఖాతాని|$1 ఖాతాలను}} సృష్టించారు, ఈ కాల వ్యవధిలో అది గరిష్ఠ పరిమితి.
 అందువల్ల, ఈ ఐపీని వాడుతున్న సందర్శకులు ప్రస్తుతానికి ఇంక ఖాతాలని సృష్టించలేరు.',
 'emailauthenticated' => 'మీ ఈ-మెయిలు చిరునామా $2న $3కి ధృవీకరింపబడింది.',
 'emailnotauthenticated' => 'మీ ఈ-మెయిలు చిరునామాను ఇంకా ధృవీకరించలేదు. 
 కింద పేర్కొన్న అంశాలకు సంబంధించి ఎటువంటి ఈ-మెయిలునూ పంపించము.',
-'noemailprefs' => 'à°\95à°¿à°\82ది à°\85à°\82శాలà±\81 à°ªà°¨à°¿ à°\9aà±\86à°¯à±\8dà°¯à°\9fానిà°\95à°¿ à°\88-à°®à±\86యిలà±\81 à°\9aà°¿à°°à±\81నామానà±\81 à°¨à°®à±\8aà°¦à±\81à°\9aà°¯à±\8dà°¯ండి.',
+'noemailprefs' => 'à°\88 à°\85à°\82శాలà±\81 à°ªà°¨à°¿ à°\9aà±\86à°¯à±\8dయడానిà°\95à°¿ à°®à±\80 à°\85à°­à°¿à°°à±\81à°\9aà±\81à°²à±\8dà°²à±\8b à°\88à°®à±\86యిలà±\81 à°\9aà°¿à°°à±\81నామా à°\87à°µà±\8dà°µండి.',
 'emailconfirmlink' => 'మీ ఈ-మెయిలు చిరునామాను ధృవీకరించండి',
 'invalidemailaddress' => 'మీరు ఇచ్చిన ఈ-మెయిలు చిరునామా సరైన రీతిలో లేనందున అంగీకరించటంలేదు.
 దయచేసి ఈ-మెయిలు చిరునామాను సరైన రీతిలో ఇవ్వండి లేదా ఖాళీగా వదిలేయండి.',
@@ -705,22 +705,22 @@ $2',
 'oldpassword' => 'పాత సంకేతపదం:',
 'newpassword' => 'కొత్త సంకేతపదం:',
 'retypenew' => 'సంకేతపదం, మళ్ళీ',
-'resetpass_submit' => 'à°¸à°\82à°\95à±\87తపదానà±\8dని à°®à°¾à°°à±\8dà°\9aà°¿ à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aండి',
+'resetpass_submit' => 'à°¸à°\82à°\95à±\87తపదానà±\8dని à°®à°¾à°°à±\8dà°\9aà°¿ à°²à°¾à°\97ినవండి',
 'changepassword-success' => 'మీ సంకేతపదం విజయవంతంగా మార్చబడింది.',
 'changepassword-throttled' => 'కొద్దిసేపటిగా మీరు చాలా లాగిన్ ప్రయత్నాలు చేసారు.
 మళ్ళీ ప్రయత్నించే ముందు $1 ఆగండి.',
 'resetpass_forbidden' => 'సంకేతపదాలను మార్చటం కుదరదు',
-'resetpass-no-info' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°¨à±\87à°°à±\81à°\97à°¾ à°\9aà±\82à°¡à°\9fానిà°\95à°¿ à°®à±\80à°°à±\81 à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿వుండాలి.',
+'resetpass-no-info' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°¨à±\87à°°à±\81à°\97à°¾ à°\9aà±\82à°¡à°\9fానిà°\95à°¿ à°®à±\80à°°à±\81 à°²à°¾à°\97ినయి వుండాలి.',
 'resetpass-submit-loggedin' => 'సంకేతపదాన్ని మార్చు',
 'resetpass-submit-cancel' => 'రద్దుచేయి',
 'resetpass-wrong-oldpass' => 'తప్పుడు తాత్కాలిక లేదా ప్రస్తుత సంకేతపదం.
 మీరు మీ సంకేతపదాన్ని ఇప్పటికే విజయవంతంగా మార్చుకొనివుండవచ్చు లేదా కొత్త తాత్కాలిక సంకేతపదం కోసం అభ్యర్థించారు.',
 'resetpass-recycled' => 'మీ ప్రస్తుత సంకేతపదాన్ని వేరే సంకేతపదంతో మార్చుకోండి',
-'resetpass-temp-emailed' => 'à°®à±\80à°°à±\81 à°®à±\80 à°\88à°®à±\86యిలà±\81à°\95à±\81 à°ªà°\82పిà°\82à°\9aà°¿à°¨ à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°\95à±\8bà°¡à±\81à°¤à±\8b à°²à±\8bపలిà°\95à°¿ à°µà°\9aà±\8dà°\9aారà±\81. à°ªà±\8dà°°à°µà±\87à°¶à°\82 à°ªà±\82à°°à±\8dతి à°\95ావడానిà°\95à°¿, à°\87à°\95à±\8dà°\95à°¡ à°®à±\80à°°à±\81 à°¤à°ªà±\8dపనిసరిà°\97à°¾ à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°\95à±\87తపదà°\82 à°\87à°µà±\8dవాలి:',
+'resetpass-temp-emailed' => 'à°®à±\80à°°à±\81 à°®à±\80 à°\88à°®à±\86యిలà±\81à°\95à±\81 à°ªà°\82పిà°\82à°\9aà°¿à°¨ à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°\95à±\8bà°¡à±\81à°¤à±\8b à°²à°¾à°\97ినయà±\8dయారà±\81. à°²à°¾à°\97à°¿à°¨à±\8dà°¨à±\81 à°ªà±\82à°°à±\8dతి à°\9aà±\87à°¸à±\87à°\82à°¦à±\81à°\95à±\81, à°\87à°\95à±\8dà°\95à°¡ à°®à±\80à°°à±\81 à°¤à°ªà±\8dపనిసరిà°\97à°¾ à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bవాలి:',
 'resetpass-temp-password' => 'తాత్కాలిక సంకేతపదం:',
 'resetpass-abort-generic' => 'ఓ పొడిగింత (ఎక్స్టెన్‍షన్) సంకేతపదం మార్పిడిని ఆపేసింది.',
 'resetpass-expired' => 'మీ సంకేతపదానికి కాలం చెల్లింది. కొత్త సంకేతపదం ఇచ్చి లాగినవండి.',
-'resetpass-expired-soft' => 'మీ సంకేతపదానికి కాలం చెల్లింది, కాబట్టి కొత్తది ఇవ్వాలి. కొత్తది ఇప్పుడే ఇవ్వండి లేదా రద్దు నొక్కి, తరువాత మార్చుకోండి.',
+'resetpass-expired-soft' => 'మీ సంకేతపదానికి కాలం చెల్లింది, కాబట్టి కొత్తది ఇవ్వాలి. కొత్తది ఇప్పుడే ఇవ్వండి లేదా "{{int:resetpass-submit-cancel}}" నొక్కి, తరువాత మార్చుకోండి.',
 
 # Special:PasswordReset
 'passwordreset' => 'సంకేతపదాన్ని మార్చుకోండి',
@@ -759,7 +759,7 @@ $2
 'changeemail' => 'ఈ-మెయిలు చిరునామా మార్పు',
 'changeemail-header' => 'ఖాతా ఈ-మెయిల్ చిరునామాని మార్చండి',
 'changeemail-text' => 'మీ ఈమెయిలు చిరునామాని మార్చుకోడానికి ఈ ఫారాన్ని నింపండి. ఈ మార్పుని నిర్ధారించడానికి మీ సంకేతపదాన్ని ఇవ్వాల్సివస్తుంది.',
-'changeemail-no-info' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°¨à±\87à°°à±\81à°\97à°¾ à°\9aà±\82à°¡à°\9fానిà°\95à°¿ à°®à±\80à°°à±\81 à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿వుండాలి.',
+'changeemail-no-info' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°¨à±\87à°°à±\81à°\97à°¾ à°\9aà±\82à°¡à°\9fానిà°\95à°¿ à°®à±\80à°°à±\81 à°²à°¾à°\97ినయి వుండాలి.',
 'changeemail-oldemail' => 'ప్రస్తుత ఈ-మెయిలు చిరునామా:',
 'changeemail-newemail' => 'కొత్త ఈ-మెయిలు చిరునామా:',
 'changeemail-none' => '(ఏమీలేదు)',
@@ -810,33 +810,33 @@ $2
 'showpreview' => 'మునుజూపు చూపు',
 'showlivepreview' => 'తక్షణ మునుజూపు',
 'showdiff' => 'తేడాలను చూపించు',
-'anoneditwarning' => "'''హెచ్చరిక:''' మీరు లోనికి ప్రవేశించలేదు.
-ఈ పేజీ దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.",
-'anonpreviewwarning' => "''మీరు లోనికి ప్రవేశించలేదు. భద్రపరిస్తే ఈ పేజీ యొక్క దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.''",
-'missingsummary' => "'''గుర్తు చేస్తున్నాం:''' మీరు దిద్దుబాటు సారాంశమేమీ ఇవ్వలేదు. పేజీని మళ్ళీ భద్రపరచమని చెబితే సారాంశమేమీ లేకుండానే దిద్దుబాటును భద్రపరుస్తాం.",
+'anoneditwarning' => '<strong>హెచ్చరిక:</strong> మీరు లాగినవలేదు.
+ఈ పేజీ దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.',
+'anonpreviewwarning' => '<em>మీరు లాగినవలేదు. భద్రపరిస్తే ఈ పేజీ యొక్క దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.</em>',
+'missingsummary' => '<strong>గుర్తు చేస్తున్నాం:</strong> మీరు దిద్దుబాటు సారాంశమేమీ ఇవ్వలేదు. పేజీని మళ్ళీ భద్రపరచమని చెబితే సారాంశమేమీ లేకుండానే దిద్దుబాటును భద్రపరుస్తాం.',
 'missingcommenttext' => 'కింద ఓ వ్యాఖ్య రాయండి.',
-'missingcommentheader' => "'''గుర్తు చేస్తున్నాం''': ఈ వ్యాఖ్యకు మీరు విషయం/శీర్షిక పెట్టలేదు.
-\"{{int:savearticle}}\"ని మళ్ళీ నొక్కితే, మీ మార్పుకి విషయం/శీర్షిక ఏమీ లేకుండానే భద్రపరుస్తాం.",
+'missingcommentheader' => '<strong>గుర్తు చేస్తున్నాం:</strong> ఈ వ్యాఖ్యకు మీరు విషయం/శీర్షిక పెట్టలేదు.
+"{{int:savearticle}}"ని మళ్ళీ నొక్కితే, అది లేకుండానే మీ మార్పును భద్రపరుస్తాం.',
 'summary-preview' => 'సారాంశం మునుజూపు:',
 'subject-preview' => 'విషయం/శీర్షిక మునుజూపు:',
 'blockedtitle' => 'వాడుకరి నిరోధించబడ్డారు',
-'blockedtext' => "'''మీ వాడుకరి పేరుని లేదా ఐ.పీ. చిరునామాని నిరోధించారు.'''
+'blockedtext' => "<strong>మీ వాడుకరి పేరు లేదా ఐ.పీ. చిరునామా నిరోధించబడింది.</strong>
 
 నిరోధించినది $1.
-అందుకు ఇచ్చిన కారణం: ''$2''
+అందుకు ఇచ్చిన కారణం: <em>$2</em>.
 
 * నిరోధం మొదలైన సమయం: $8
 * నిరోధించిన కాలం: $6
 * నిరోధానికి గురైనవారు: $7
 
-ఈ నిరోధంపై చర్చించేందుకు మీరు $1ను గాని, మరెవరైనా [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకులను]] గాని సంప్రదించవచ్చు.
+ఈ నిరోధంపై చర్చించేందుకు మీరు $1 ను గాని, మరెవరైనా [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకులను]] గాని సంప్రదించవచ్చు.
 మీ [[Special:Preferences|ఖాతా అభిరుచులలో]] సరైన ఈ-మెయిలు చిరునామా ఇచ్చివుండకపోయినా లేదా మిమ్మల్ని  'ఈ వాడుకరికి ఈ-మెయిలు పంపు' సౌలభ్యాన్ని వాడుకోవడం నుండి నిరోధించివున్నా మీరు ఈమెయిలు ద్వారా సంప్రదించలేరు.
 మీ ప్రస్తుత ఐ.పీ. చిరునామా $3, మరియు నిరోధపు ID #$5.
 మీ సంప్రదింపులన్నిటిలోనూ వీటిని పేర్కొనండి.",
 'autoblockedtext' => 'మీ ఐపీ చిరునామా ఆటోమాటిగ్గా నిరోధించబడింది. ఎందుకంటే ఇదే ఐపీ చిరునామాని ఓ నిరోధిత వాడుకరి ఉపయోగించారు. ఆ వాడుకరిని $1 నిరోధించారు.
 అందుకు ఇచ్చిన కారణం ఇదీ:
 
-:\'\'$2\'\'
+:<em>$2</em>
 
 * నిరోధం మొదలైన సమయం: $8
 * నిరోధించిన కాలం: $6
@@ -850,19 +850,23 @@ $2
 మీ సంప్రదింపులన్నిటిలోను అన్ని పై వివరాలను ఉదహరించండి.',
 'blockednoreason' => 'కారణమేమీ ఇవ్వలేదు',
 'whitelistedittext' => 'పుటలలో మార్పులు చెయ్యడానికి $1.',
-'confirmedittext' => 'పేజీల్లో మార్పులు చేసేముందు మీ ఈ-మెయిలు చిరునామా ధృవీకరించాలి. [[Special:Preferences|మీ అభిరుచుల]]లో మీ ఈ-మెయిలు చిరునామా రాసి, ధృవీకరించండి.',
+'confirmedittext' => 'పేజీల్లో మార్పులు చేసేముందు మీ ఈమెయిలు చిరునామాను ధృవీకరించాలి. [[Special:Preferences|మీ అభిరుచుల]]లో మీ ఈమెయిలు చిరునామా రాసి, ధృవీకరించండి.',
 'nosuchsectiontitle' => 'విభాగాన్ని కనగొనలేకపోయాం',
-'nosuchsectiontext' => 'à°®à±\80à°°à±\81 à°²à±\87ని à°µà°¿à°­à°¾à°\97ానà±\8dని à°®à°¾à°°à±\8dà°\9aడానిà°\95à°¿ ప్రయత్నించారు.
+'nosuchsectiontext' => 'à°\85సలà±\81 à°²à±\87à°¨à±\87 à°²à±\87ని à°µà°¿à°­à°¾à°\97ానà±\8dని à°®à°¾à°°à±\8dà°\9aడానిà°\95à°¿ à°®à±\80à°°à±\81 ప్రయత్నించారు.
 మీరు పేజీని చూస్తూన్నప్పుడు దాన్ని ఎవరైనా తరలించి లేదా తొలగించి ఉండవచ్చు.',
-'loginreqtitle' => 'à°ªà±\8dà°°à°µà±\87శమà±\81 తప్పనిసరి',
+'loginreqtitle' => 'లాà°\97ినవడà°\82 తప్పనిసరి',
 'loginreqlink' => 'లాగినవండి',
-'loginreqpagetext' => 'ఇతర పుటలను చూడడానికి మీరు $1 ఉండాలి.',
+'loginreqpagetext' => 'ఇతర పుటలను చూడడానికి $1.',
 'accmailtitle' => 'సంకేతపదం పంపించబడింది.',
 'accmailtext' => "[[User talk:$1|$1]] కొరకు ఒక యాదృచ్ఛిక సంకేతపదాన్ని $2కి పంపించాం. లాగినయ్యాక, ''[[Special:ChangePassword|సంకేతపదాన్ని మార్చుకోండి]]'' అనే పేజీలో ఈ సంకేతపదాన్ని మార్చుకోవచ్చు.",
 'newarticle' => '(కొత్తది)',
-'newarticletext' => "ఈ లింకుకు సంబంధించిన పేజీ ఉనికిలొ లేదు.
-కింది పెట్టెలో మీ రచనను టైపు చేసి ఆ పేజీని సృష్టించండి (దీనిపై సమాచారం కొరకు [[{{MediaWiki:Helppage}}|సహాయం]] పేజీ చూడండి). మీరిక్కడికి పొరపాటున వచ్చి ఉంటే, మీ బ్రౌజరు '''back''' మీట నొక్కండి.",
-'anontalkpagetext' => "----''ఇది ఒక అజ్ఞాత వాడుకరి చర్చా పేజీ. ఆ వాడుకరి ఇంకా తనకై ఖాతాను సృష్టించుకోలేదు, లేదా ఖాతా ఉన్నా దానిని ఉపయోగించడం లేదు. అజ్ఞాత వాడుకరులను గుర్తించడానికి అంకెలతో ఉండే ఐ.పీ. చిరునామాను వాడుతాం. కానీ, ఒకే ఐ.పీ. చిరునామాని చాలా మంది వాడుకరులు ఉపయోగించే అవకాశం ఉంది. మీరు అజ్ఞాత వాడుకరి అయితే మరియు సంబంధంలేని వ్యాఖ్యలు మిమ్మల్ని ఉద్దేశించినట్టుగా అనిపిస్తే, భవిష్యత్తులో ఇతర అజ్ఞాత వాడుకరులతో అయోమయం లేకుండా ఉండటానికి, దయచేసి [[Special:UserLogin/signup|ఖాతాను సృష్టించుకోండి]] లేదా [[Special:UserLogin|లోనికి ప్రవేశించండి]].''",
+'newarticletext' => 'ఈ లింకుకు సంబంధించిన పేజీ లేనే లేదు.
+కింది పెట్టెలో మీ రచనను టైపు చేసి ఆ పేజీని సృష్టించండి (దీనిపై సమాచారం కొరకు [[{{MediaWiki:Helppage}}|సహాయం పేజీ]] చూడండి). మీరిక్కడికి పొరపాటున వచ్చి ఉంటే, మీ బ్రౌజరు <strong>back</strong> మీట నొక్కండి.',
+'anontalkpagetext' => "----
+<em>ఇది ఒక అజ్ఞాత వాడుకరి చర్చా పేజీ. ఆ వాడుకరి ఇంకా తనకై ఖాతాను సృష్టించుకోలేదు, లేదా ఖాతా ఉన్నా దానిని ఉపయోగించడం లేదు.</em>
+అంచేత, అతణ్ణి/ఆమెను గుర్తించడానికి ఐ.పీ. చిరునామాను వాడాల్సి వచ్చింది. 
+ఒకే ఐ.పీ. చిరునామాని చాలా మంది వాడుకరులు ఉపయోగించే అవకాశం ఉంది. 
+మీరూ అజ్ఞాత వాడుకరి అయితే, మీకు సంబంధంలేని వ్యాఖ్యలు మిమ్మల్ని ఉద్దేశించినట్టుగా అనిపిస్తే, భవిష్యత్తులో ఇతర అజ్ఞాత వాడుకరులతో అయోమయం లేకుండా ఉండటానికి, [[Special:UserLogin/signup|ఖాతాను సృష్టించుకోండి]] లేదా [[Special:UserLogin|లాగినవండి]].''",
 'noarticletext' => 'ప్రస్తుతం ఈ పేజీలో పాఠ్యమేమీ లేదు.
 వేరే పేజీలలో [[Special:Search/{{PAGENAME}}|ఈ పేజీ శీర్షిక కోసం వెతకవచ్చు]],
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} సంబంధిత చిట్టాలు చూడవచ్చు],
@@ -870,7 +874,7 @@ $2
 'noarticletext-nopermission' => 'ప్రస్తుతం ఈ పేజీలో పాఠ్యమేమీ లేదు.
 మీరు ఇతర పేజీలలో [[Special:Search/{{PAGENAME}}|ఈ పేజీ శీర్షిక కోసం వెతకవచ్చు]], లేదా <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} సంబంధిత చిట్టాలలో వెతకవచ్చు]</span>, కానీ ఈ పేజీని సృష్టించడానికి మీకు అనుమతి లేదు.',
 'missing-revision' => '"{{PAGENAME}}" అనే పేజీ యొక్క కూర్పు #$1 ఉనికిలో లేదు. సాధారణంగా ఏదైనా తొలగించబడిన పేజీ యొక్క కాలం చెల్లిన చరితం లింకును నొక్కినపుడు ఇది జరుగుతుంది. వివరాలు [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు లాగ్] లో దొరుకుతాయి.',
-'userpage-userdoesnotexist' => '"<nowiki>$1</nowiki>" అనే వాడుకరి ఖాతా నమోదయిలేదు. మీరు ఈ పేజీని సృష్టించ/సరిదిద్దాలనుకుంటే, సరిచూసుకోండి.',
+'userpage-userdoesnotexist' => '"$1" అనే వాడుకరి ఖాతా నమోదయిలేదు. మీరు ఈ పేజీని సృష్టించాలని/సరిదిద్దాలని అనుకుంటున్నారేమో చూడండి.',
 'userpage-userdoesnotexist-view' => 'వాడుకరి ఖాతా "$1" నమోదుకాలేదు.',
 'blocked-notice-logextract' => 'ప్రస్తుతం ఈ వాడుకరిని నిరోధించారు.
 నిరోధపు చిట్టాలోని చివరి పద్దుని మీ సమాచారం కోసం ఈ క్రింద ఇస్తున్నాం:',
@@ -879,37 +883,37 @@ $2
 * <strong>గూగుల్ క్రోమ్:</strong> <em>Ctrl-Shift-R</em> (మాక్ లో <em>⌘-Shift-R</em>) నొక్కండి
 *<strong>ఇంటర్నెట్ ఎక్ప్లోరర్:</strong> <em>Ctrl</em> ను నొక్కిపట్టి <em>Refresh</em> నొక్కండి లేదా <em>Ctrl-F5</em> నొక్కండి.
 *<em>ఒపెరా:</em> <em>Tools → Preferences</em> ద్వారా కోశాన్ని ఖాళీ చెయ్యండి',
-'usercssyoucanpreview' => "'''చిట్కా:''' భద్రపరిచేముందు మీ కొత్త CSSని పరీక్షించడానికి \"{{int:showpreview}}\" అనే బొత్తాన్ని వాడండి.",
-'userjsyoucanpreview' => "'''చిట్కా:''' భద్రపరిచేముందు మీ కొత్త జావాస్క్రిప్టుని పరీక్షించడానికి \"{{int:showpreview}}\" అనే బొత్తాన్ని వాడండి.",
-'usercsspreview' => "'''మీరు వాడుకరి CSSను కేవలం సరిచూస్తున్నారని గుర్తుంచుకోండి.'''
-'''దాన్నింకా భద్రపరచలేదు!'''",
-'userjspreview' => "'''గుర్తుంచుకోండి, మీరింకా మీ వాడుకరి జావాస్క్రిప్ట్&zwnj;ను భద్రపరచలేదు, కేవలం పరీక్షిస్తున్నారు/సరిచూస్తున్నారు!'''",
+'usercssyoucanpreview' => '<strong>చిట్కా:</strong> భద్రపరిచేముందు మీ కొత్త CSSని పరీక్షించడానికి "{{int:showpreview}}" బొత్తాన్ని వాడండి.',
+'userjsyoucanpreview' => '<strong>చిట్కా:</strong> భద్రపరిచేముందు మీ కొత్త జావాస్క్రిప్టుని పరీక్షించడానికి "{{int:showpreview}}" బొత్తాన్ని వాడండి.',
+'usercsspreview' => '<strong>మీరు వాడుకరి CSSను కేవలం సరిచూస్తున్నారని గుర్తుంచుకోండి.
+దాన్నింకా భద్రపరచలేదు!</strong>',
+'userjspreview' => '<strong>గుర్తుంచుకోండి, మీరింకా మీ వాడుకరి జావాస్క్రిప్ట్&zwnj;ను భద్రపరచలేదు, కేవలం పరీక్షిస్తున్నారు/సరిచూస్తున్నారు!</strong>',
 'sitecsspreview' => "'''మీరు చూస్తున్నది ఈ CSS మునుజూపును మాత్రమేనని గుర్తుంచుకోండి.'''
 '''దీన్నింకా భద్రపరచలేదు!'''",
 'sitejspreview' => "'''మీరు చూస్తున్నది ఈ JavaScript మునుజూపును మాత్రమేనని గుర్తుంచుకోండి.''' 
 '''దీన్నింకా భద్రపరచలేదు!'''",
-'userinvalidcssjstitle' => "'''హెచ్చరిక:''' \"\$1\" అనే అలంకారం లేదు.
-అభిమత .css మరియు .js పుటల శీర్షికలు ఇంగ్లీషు చిన్నబడి అక్షరాల లోనే ఉండాలని గుర్తుంచుకోండి, ఉదాహరణకు ఇలా {{ns:user}}:Foo/vector.css అంతేగానీ, {{ns:user}}:Foo/Vector.css ఇలా కాదు.",
+'userinvalidcssjstitle' => '<strong>హెచ్చరిక:</strong> "$1" అనే రూపు లేదు.
+అభిమత .css మరియు .js పుటల శీర్షికలు ఇంగ్లీషు చిన్నబడి అక్షరాల లోనే ఉండాలని గుర్తుంచుకోండి, ఉదాహరణకు ఇలా {{ns:user}}:Foo/vector.css అంతేగానీ, {{ns:user}}:Foo/Vector.css ఇలా కాదు.',
 'updated' => '(నవీకరించబడింది)',
-'note' => "'''గమనిక:'''",
-'previewnote' => "'''ఇది మునుజూపు మాత్రమేనని గుర్తుంచుకోండి.'''
-మీ మార్పులు ఇంకా భద్రమవ్వలేదు!",
+'note' => '<strong>గమనిక:</strong>',
+'previewnote' => '<strong>ఇది మునుజూపు మాత్రమేనని గుర్తుంచుకోండి.</strong>
+మీ మార్పులు ఇంకా భద్రమవ్వలేదు!',
 'continue-editing' => 'సరిదిద్దే చోటుకి వెళ్ళండి',
 'previewconflict' => 'భద్రపరచిన తరువాత పై టెక్స్ట్‌ ఏరియాలోని టెక్స్టు ఇలాగ కనిపిస్తుంది.',
 'session_fail_preview' => "'''క్షమించండి! సెషను డేటా పోవడం వలన మీ మార్పులను స్వీకరించలేకపోతున్నాం.'''
 దయచేసి మళ్ళీ ప్రయత్నించండి.
 అయినా పని జరక్కపోతే, ఓసారి [[Special:UserLogout|నిష్క్రమించి]] మళ్ళీ లోనికి ప్రవేశించి ప్రయత్నించండి.",
-'session_fail_preview_html' => "'''సారీ! సెషను డేటా పోవడం వలన మీ దిద్దుబాటును ప్రాసెస్ చెయ్యలేలేక పోతున్నాం.'''
+'session_fail_preview_html' => "<strong>సారీ! సెషను డేటా పోవడం వలన మీ దిద్దుబాటును ప్రాసెస్ చెయ్యలేలేక పోతున్నాం.</strong>
 
 ''{{SITENAME}}లో ముడి HTML సశక్తమై ఉంది కాబట్టి, జావాస్క్రిప్టు దాడుల నుండి రక్షణగా మునుజూపును దాచేశాం.''
 
-'''మీరు చేసినది సరైన దిద్దుబాటే అయితే, మళ్ళీ ప్రయత్నించండి. అయినా పనిచెయ్యకపోతే, ఓ సారి లాగౌటయ్యి, మళ్ళీ లాగినయి చూడండి.'''",
+<strong>మీరు చేసినది సరైన దిద్దుబాటే అయితే, మళ్ళీ ప్రయత్నించండి. అయినా పనిచెయ్యకపోతే, ఓ సారి [[Special:UserLogout|లాగౌటై]], మళ్ళీ లాగినయి చూడండి.</strong>",
 'token_suffix_mismatch' => "'''మీ క్లయంటు, దిద్దుబాటు టోకెన్‌లోని వ్యాకరణ గుర్తులను గజిబిజి చేసింది కాబట్టి మీ దిద్దుబాటును తిరస్కరించాం. పేజీలోని పాఠ్యాన్ని చెడగొట్టకుండా ఉండేందుకు గాను, ఆ దిద్దుబాటును రద్దు చేశాం. వెబ్‌లో ఉండే లోపభూయిష్టమైన అజ్ఞాత ప్రాక్సీ సర్వీసులను వాడినపుడు ఒక్కోసారి ఇలా జరుగుతుంది.'''",
 'edit_form_incomplete' => '’’’ఈ ఎడిట్ ఫారంలోని కొన్ని భాగాలు సర్వరును చేరలేదు; మీ మార్పుచేర్పులు భద్రంగా ఉన్నాయని ధృవపరచుకుని, మళ్ళీ ప్రయత్నించండి.’’’',
-'editing' => '$1కి మార్పులు',
+'editing' => '$1 ని సవరిస్తున్నారు',
 'creating' => '$1 పేజీని సృష్టిస్తున్నారు',
-'editingsection' => '$1కు మార్పులు (విభాగం)',
-'editingcomment' => '$1 à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fు (కొత్త విభాగం)',
+'editingsection' => '$1 ని సవరిస్తున్నారు (విభాగం)',
+'editingcomment' => '$1 à°¨à°¿ à°¸à°µà°°à°¿à°¸à±\8dà°¤à±\81à°¨à±\8dనారు (కొత్త విభాగం)',
 'editconflict' => 'దిద్దుబాటు ఘర్షణ: $1',
 'explainconflict' => "మీరు మార్పులు చెయ్యడం మొదలుపెట్టిన తరువాత, వేరే ఎవరో ఈ పుటని మార్పారు.
 పైన ఉన్న పాఠ్య పేటికలో ఈ పుట యొక్క ప్రస్తుతపు పాఠ్యం ఉంది.
@@ -918,24 +922,25 @@ $2
 మీరు \"{{int:savearticle}}\"ను నొక్కినపుడు, పై పాఠ్య పేటికలో ఉన్న పాఠ్యం '''మాత్రమే''' భద్రపరచబడుతుంది.",
 'yourtext' => 'మీ పాఠ్యం',
 'storedversion' => 'భద్రపరచిన కూర్పు',
-'nonunicodebrowser' => "'''WARNING: Your browser is not unicode compliant. A workaround is in place to allow you to safely edit pages: non-ASCII characters will appear in the edit box as hexadecimal codes.'''",
-'editingold' => "'''హెచ్చ రిక: ఈ పేజీ యొక్క కాలం చెల్లిన సంచికను మీరు మరుస్తున్నారు. దీనిని భద్రపరిస్తే, ఆ సంచిక తరువాత ఈ పేజీలో జరిగిన మార్పులన్నీ పోతాయి.'''",
+'nonunicodebrowser' => '<strong>హెచ్చరిక: మీ బ్రౌజరు యూనికోడుకు అనుకూలంగా లేదు.</strong>
+పేజీలను క్షేమంగా సవరించేందుకు ఓ దారి ఉంది: ASCII యేతర కారెక్టర్లు ఎడిట్ పెట్టెలో హెక్సాడెసిమల్ కోడ్‍లుగా కనిపిస్తాయి.',
+'editingold' => '<strong>హెచ్చ రిక: ఈ పేజీ యొక్క కాలం చెల్లిన సంచికను మీరు మరుస్తున్నారు.</strong> దీనిని భద్రపరిస్తే, ఆ సంచిక తరువాత జరిగిన మార్పులన్నీ పోతాయి.',
 'yourdiff' => 'తేడాలు',
-'copyrightwarning' => "{{SITENAME}}కు సమర్పించే అన్ని రచనలూ $2కు లోబడి ప్రచురింపబడినట్లుగా భావించబడతాయి (వివరాలకు $1 చూడండి). మీ రచనలను ఎవ్వరూ మార్చ రాదనీ లెదా వేరే ఎవ్వరూ వాడుకో రాదని మీరు భావిస్తే, ఇక్కడ ప్రచురించకండి.<br /> మీ స్వీయ రచనను గాని, సార్వజనీనమైన రచననుగాని, ఇతర ఉచిత వనరుల నుండి సేకరించిన రచననుగాని మాత్రమే ప్రచురిస్తున్నానని కూడా మీరు ప్రమాణం చేస్తున్నారు. '''కాపీహక్కులుగల రచనను తగిన అనుమతి లేకుండా సమర్పించకండి!'''",
-'copyrightwarning2' => "{{SITENAME}}లో ప్రచురించే రచనలన్నిటినీ ఇతర రచయితలు సరిదిద్దడం, మార్చడం, తొలగించడం చేసే అవకాశం ఉంది. మీ రచనలను అలా నిర్దాక్షిణ్యంగా దిద్దుబాట్లు చెయ్యడం మీకిష్టం లేకపోతే, వాటిని ఇక్కడ ప్రచురించకండి. <br />
-à°\88 à°°à°\9aననà±\81 à°®à±\80à°°à±\87 à°\9aà±\87సారని, à°²à±\87దా à°\8fà°¦à±\88నా à°¸à°¾à°°à±\8dà°µà°\9cనిà°\95 à°µà°¨à°°à±\81 à°¨à±\81à°\82à°¡à°¿ à°\95ాపà±\80 à°\9aà±\87సి à°¤à±\86à°\9aà±\8dà°\9aారని, à°²à±\87దా à°\85లాà°\82à°\9fà°¿ à°\89à°\9aà°¿à°¤, à°¸à±\8dà°µà±\87à°\9aà±\8dà°\9bà°¾ à°µà°¨à°°à±\81 à°¨à±\81à°\82à°¡ి తెచ్చారని మాకు వాగ్దానం చేస్తున్నారు. (వివరాలకు $1 చూడండి).
-'''తగు అనుమతులు లేకుండా కాపీ హక్కులు గల రచనలను సమర్పించకండి!'''",
-'longpageerror' => "'''పొరపాటు: మీరు సమర్పించిన పాఠ్యం, గరిష్ఠ పరిమితి అయిన {{PLURAL:$2|ఒక కిలోబైటుని|$2 కిలోబైట్లను}} మించి {{PLURAL:$1|ఒక కిలోబైటు|$1 కిలోబైట్ల}} పొడవుంది.'''
- దీన్ని భద్రపరచలేము.",
+'copyrightwarning' => '{{SITENAME}}కు సమర్పించే అన్ని రచనలూ $2కు లోబడి ప్రచురింపబడినట్లుగా భావించబడతాయి (వివరాలకు $1 చూడండి). మీ రచనలను ఎవ్వరూ మార్చ రాదనీ లెదా వేరే ఎవ్వరూ వాడుకో రాదని మీరు భావిస్తే, ఇక్కడ ప్రచురించకండి.<br /> మీ స్వీయ రచనను గాని, సార్వజనీనమైన రచననుగాని, ఇతర ఉచిత వనరుల నుండి సేకరించిన రచననుగాని మాత్రమే ప్రచురిస్తున్నానని కూడా మీరు ప్రమాణం చేస్తున్నారు. <strong>కాపీహక్కులుగల రచనను తగిన అనుమతి లేకుండా సమర్పించకండి!</strong>',
+'copyrightwarning2' => '{{SITENAME}}లో ప్రచురించే రచనలన్నిటినీ ఇతర రచయితలు సరిదిద్దడం, మార్చడం, తొలగించడం జరగవచ్చు. మీ రచనలను అలా నిర్దాక్షిణ్యంగా దిద్దుబాట్లు చెయ్యడం మీకిష్టం లేకపోతే, వాటిని ఇక్కడ ప్రచురించకండి. <br />
+à°\85లాà°\97à±\87, à°\88 à°°à°\9aననà±\81 à°®à±\80à°°à±\87 à°\9aà±\87సారని, à°²à±\87దా à°\8fà°¦à±\88నా à°¸à°¾à°°à±\8dà°µà°\9cనిà°\95 à°µà°¨à°°à±\81 à°¨à±\81à°\82à°¡à°¿ à°\97ానà±\80, à°\85లాà°\82à°\9fà°¿ à°\89à°\9aà°¿à°¤, à°¸à±\8dà°µà±\87à°\9aà±\8dà°\9bà°¾ à°µà°¨à°°à±\81 à°¨à±\81à°\82à°¡à°¿ à°\97ానà±\80 à°\95ాపà±\80 à°\9aà±\87à°¸ి తెచ్చారని మాకు వాగ్దానం చేస్తున్నారు. (వివరాలకు $1 చూడండి).
+<strong>తగు అనుమతులు లేకుండా కాపీ హక్కులు గల రచనలను సమర్పించకండి!</strong>',
+'longpageerror' => '<strong>లోపం: మీరు సమర్పించిన పాఠ్యం {{PLURAL:$1|ఒక కిలోబైటు|$1 కిలోబైట్ల}} నిడివి కలిగి ఉంది. ఇది గరిష్ఠ పరిమితి అయిన {{PLURAL:$2|ఒక కిలోబైటుని|$2 కిలోబైట్లను}} మించింది.</strong>
+ దీన్ని భద్రపరచలేము.',
 'readonlywarning' => '<strong>హెచ్చరిక: నిర్వహణ కొరకు డేటాబేసుకి తాళం వేసారు. కాబట్టి మీ మార్పుచేర్పులను ఇప్పుడు భద్రపరచలేరు.</strong> 
 మీ మార్పులను ఒక ఫాఠ్య ఫైలులోకి కాపీ చేసి భద్రపరచుకొని, తరువాత సమర్పించండి.
 
 తాళం వేసిన నిర్వాహకుడి వివరణ ఇదీ: $1',
-'protectedpagewarning' => "'''హెచ్చరిక: ఈ పేజీ సంరక్షించబడినది, కనుక నిర్వాహక అనుమతులు ఉన్న వాడుకరులు మాత్రమే మార్చగలరు.'''
-à°\9aివరి à°\9aà°¿à°\9fà±\8dà°\9fà°¾ à°ªà°¦à±\8dà°¦à±\81ని à°®à±\80 à°¸à°®à°¾à°\9aారà°\82 à°\95à±\8bà°¸à°\82 à°\87à°\95à±\8dà°\95à°¡ à°\87à°¸à±\8dà°¤à±\81à°¨à±\8dనాà°\82:",
-'semiprotectedpagewarning' => "'''గమనిక:''' నమోదయిన వాడుకరులు మాత్రమే మార్పులు చెయ్యగలిగేలా ఈ పేజీకి సంరక్షించారు.
-à°®à±\80 à°¸à°®à°¾à°\9aారà°\82 à°\95à±\8bà°¸à°\82 à°\9aివరి à°\9aà°¿à°\9fà±\8dà°\9fà°¾ à°ªà°¦à±\8dà°¦à±\81ని à°\87à°\95à±\8dà°\95à°¡ à°\87à°¸à±\8dà°¤à±\81à°¨à±\8dనాà°\82:",
-'cascadeprotectedwarning' => "'''హెచ్చరిక:''' ఈ పేజీ, కాస్కేడింగు రక్షణలో ఉన్న కింది {{PLURAL:$1|పేజీ|పేజీల్లో}} ఇంక్లూడు అయి ఉంది కాబట్టి, నిర్వాహకులు తప్ప ఇతరులు దిద్దుబాటు చేసే వీలు లేకుండా పేజీని లాకు చేసాం:",
+'protectedpagewarning' => '<strong>హెచ్చరిక: ఈ పేజీ సంరక్షించబడింది. కాబట్టి నిర్వాహక అనుమతులు ఉన్న వాడుకరులు మాత్రమే మార్చగలరు.</strong>
+à°\9aివరి à°²à°¾à°\97à±\8d à°ªà°¦à±\8dà°¦à±\81à°¨à±\81 à°®à±\80 à°¸à°®à°¾à°\9aారà°\82 à°\95à±\8bà°¸à°\82 à°\87à°\95à±\8dà°\95à°¡ à°\87à°¸à±\8dà°¤à±\81à°¨à±\8dనాà°\82:',
+'semiprotectedpagewarning' => '<strong>గమనిక:</strong> నమోదయిన వాడుకరులు మాత్రమే మార్పులు చెయ్యగలిగేలా ఈ పేజీకి సంరక్షించారు.
+à°®à±\80 à°¸à°®à°¾à°\9aారà°\82 à°\95à±\8bà°¸à°\82 à°\9aివరి à°²à°¾à°\97à±\8d à°ªà°¦à±\8dà°¦à±\81ని à°\87à°\95à±\8dà°\95à°¡ à°\87à°¸à±\8dà°¤à±\81à°¨à±\8dనాà°\82:',
+'cascadeprotectedwarning' => "'''హెచ్చరిక:''' ఈ పేజీ, కాస్కేడింగు రక్షణలో ఉన్న కింది {{PLURAL:$1|పేజీ|పేజీల్లో}} ఇంక్లూడు అయి ఉంది కాబట్టి, నిర్వాహకులు తప్ప ఇతరులు దిద్దుబాటు చేసే వీలు లేకుండా {{PLURAL:$1|పేజీని|పేజీలను}} లాకు చేసాం:",
 'titleprotectedwarning' => "హెచ్చరిక:  ఈ పేజీని సంరక్షించారు కాబట్టి దీన్ని సృష్టించడానికి [[Special:ListGroupRights|ప్రత్యేక హక్కులు]] ఉండాలి.'''
 మీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
 'templatesused' => 'ఈ పేజీలో వాడిన {{PLURAL:$1|మూస|మూసలు}}:',
@@ -947,26 +952,26 @@ $2
 'nocreatetext' => '{{SITENAME}}లో కొత్త పేజీలు సృష్టించడాన్ని నియంత్రించారు.
 మీరు వెనక్కి వెళ్ళి వేరే పేజీలు మార్చవచ్చు, లేదా [[Special:UserLogin|లోనికి ప్రవేశించండి లేదా ఖాతా సృష్టించుకోండి]].',
 'nocreate-loggedin' => 'కొత్త పేజీలను సృష్టించేందుకు మీకు అనుమతి లేదు.',
-'sectioneditnotsupported-title' => 'విభాà°\97à°ªà±\81 à°¦à°¿à°¦à±\8dదిబాà°\9fà±\8dà°²à°\95à°¿ à°¤à±\8aడ్పాటు లేదు',
+'sectioneditnotsupported-title' => 'విభాà°\97à°ªà±\81 à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°²à°\95à±\81 à°¤à±\8bడ్పాటు లేదు',
 'sectioneditnotsupported-text' => 'ఈ పేజీలో విభాగాల దిద్దుబాటుకి తోడ్పాటు లేదు.',
 'permissionserrors' => 'అనుమతి లోపం',
 'permissionserrorstext' => 'కింద పేర్కొన్న {{PLURAL:$1|కారణం|కారణాల}} మూలంగా, ఆ పని చెయ్యడానికి మీకు అనుమతిలేదు:',
 'permissionserrorstext-withaction' => 'ఈ క్రింది {{PLURAL:$1|కారణం|కారణాల}} వల్ల, $2 అనుమతి మీకు లేదు:',
-'recreate-moveddeleted-warn' => "'''హెచ్చరిక: ఇంతకు మునుపు ఒకసారి తొలగించిన పేజీని మళ్లీ సృష్టిద్దామని మీరు ప్రయత్నిస్తున్నారు.'''
+'recreate-moveddeleted-warn' => '<strong>హెచ్చరిక: ఇంతకు మునుపు ఒకసారి తొలగించిన పేజీని మళ్లీ సృష్టిద్దామని మీరు ప్రయత్నిస్తున్నారు.</strong>
 
 ఈ పేజీపై మార్పులు చేసేముందు, అవి ఇక్కడ ఉండతగినవేనా కాదా అని ఒకసారి ఆలోచించండి.
-మీ సౌలభ్యం కొరకు ఈ పేజీ యొక్క తొలగింపు మరియు తరలింపు చిట్టా ఇక్కడ ఇచ్చాము:",
+మీ సౌలభ్యం కొరకు ఈ పేజీ యొక్క తొలగింపు మరియు తరలింపు చిట్టా ఇక్కడ ఇచ్చాము:',
 'moveddeleted-notice' => 'ఈ పేజీని తొలగించారు.
 సమాచారం కొరకు ఈ పేజీ యొక్క తొలగింపు మరియు తరలింపు చిట్టాని క్రింద ఇచ్చాం.',
 'log-fulllog' => 'పూర్తి చిట్టాని చూడండి',
-'edit-hook-aborted' => 'కొక్కెం మార్పుని విచ్ఛిన్నం చేసింది.
+'edit-hook-aborted' => 'à°\95à±\8aà°\95à±\8dà°\95à±\86à°\82 à°\88 à°®à°¾à°°à±\8dà°ªà±\81ని à°µà°¿à°\9aà±\8dà°\9bà°¿à°¨à±\8dà°¨à°\82 à°\9aà±\87సిà°\82ది.
 అది ఎటువంటి వివరణా ఇవ్వలేదు.',
-'edit-gone-missing' => 'à°ªà±\87à°\9cà±\80ని à°®à°¾à°°à±\8dà°\9aà°²à±\87à°®à±\81.
-à°¦à±\80న్ని తొలగించినట్టున్నారు.',
-'edit-conflict' => 'మారà±\8dà°ªà±\81 à°¸à°\82ఘర్షణ.',
-'edit-no-change' => 'పాఠà±\8dà°¯à°\82à°²à±\8b à°\8fà°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81 à°²à±\87à°µà±\81 à°\97à°¨à°\95, à°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81ని పట్టించుకోవట్లేదు.',
+'edit-gone-missing' => 'à°ªà±\87à°\9cà±\80ని à°¤à°¾à°\9cà°¾à°\95à°°à°¿à°\82à°\9aà°²à±\87à°\95à°ªà±\8bయాà°\82.
+దాన్ని తొలగించినట్టున్నారు.',
+'edit-conflict' => 'దిదà±\8dà°¦à±\81బాà°\9fà±\81 ఘర్షణ.',
+'edit-no-change' => 'పాఠà±\8dà°¯à°\82à°²à±\8b à°®à°¾à°°à±\8dà°ªà±\81à°²à±\87à°®à±\80 à°\9aà±\86à°¯à±\8dయలà±\87à°¦à±\81 à°\95ాబà°\9fà±\8dà°\9fà°¿, à°®à±\80 à°®à°¾à°°à±\8dà°ªà±\81à°¨à±\81 పట్టించుకోవట్లేదు.',
 'postedit-confirmation' => 'మీ మార్పు భద్రమయ్యింది.',
-'edit-already-exists' => 'à°\95à±\8aà°¤à±\8dà°¤ à°ªà±\87à°\9cà±\80ని à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà°²à±\87à°®à±\81.
+'edit-already-exists' => 'à°\95à±\8aà°¤à±\8dà°¤ à°ªà±\87à°\9cà±\80ని à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà°²à±\87à°\95à°ªà±\8bయాà°\82.
 అది ఇప్పటికే ఉంది.',
 'defaultmessagetext' => 'అప్రమేయ సందేశపు పాఠ్యం',
 'content-failed-to-parse' => '$1 మోడల్ కొరకు $2 పాఠ్యాన్ని పార్స్ చెయ్యలేకపోయాం: $3',
@@ -984,14 +989,14 @@ $2
 'content-model-css' => 'CSS',
 
 # Parser/template warnings
-'expensive-parserfunction-warning' => 'హెచ్చరిక: ఈ పేజీలో ఖరీదైన పార్సరు పిలుపులు చాలా ఉన్నాయి.
+'expensive-parserfunction-warning' => '<strong>హెచ్చరిక:</strong> ఈ పేజీలో ఖరీదైన పార్సరు పిలుపులు చాలా ఉన్నాయి.
 
 పార్సరు {{PLURAL:$2|పిలుపు|పిలుపులు}} $2 కంటే తక్కువ ఉండాలి,  ప్రస్తుతం {{PLURAL:$1|$1 పిలుపు ఉంది|$1  పిలుపులు ఉన్నాయి}}.',
 'expensive-parserfunction-category' => 'పార్సరు సందేశాలు అధికంగా ఉన్న పేజీలు',
 'post-expand-template-inclusion-warning' => '<strong>హెచ్చరిక:</strong> మూస ఇముడ్పు సైజు చాలా పెద్దదిగా ఉంది.
 కొన్ని మూసలు ఇమడ్చబడవు.',
 'post-expand-template-inclusion-category' => 'మూస చేర్పు సైజును అధిగమించిన పేజీలు',
-'post-expand-template-argument-warning' => 'హెచ్చరిక: చాల పెద్ద సైజున్న మూస ఆర్గ్యుమెంటు, కనీసం ఒకటి, ఈ పేజీలో ఉంది.
+'post-expand-template-argument-warning' => '<strong>హెచ్చరిక:</strong> చాల పెద్ద సైజున్న మూస ఆర్గ్యుమెంటు, కనీసం ఒకటి, ఈ పేజీలో ఉంది.
 ఈ ఆర్గ్యుమెంట్లను వదలివేసాం.',
 'post-expand-template-argument-category' => 'తొలగించిన మూస ఆర్గ్యుమెంట్లు ఉన్న పేజీలు',
 'parser-template-loop-warning' => 'మూస లూపు కనబడింది: [[$1]]',
@@ -1001,8 +1006,8 @@ $2
 # "Undo" feature
 'undo-success' => 'దిద్దుబాటును రద్దు చెయ్యవచ్చు. కింది పోలికను చూసి, మీరు చెయ్యదలచినది ఇదేనని నిర్ధారించుకోండి. ఆ తరువాత మార్పులను భద్రపరచి దిద్దుబాటు రద్దును పూర్తి చెయ్యండి.',
 'undo-failure' => 'మధ్యలో జరిగిన దిద్దుబాట్లతో తలెత్తిన ఘర్షణ కారణంగా ఈ దిద్దుబాటును రద్దు చెయ్యలేక పోయాం.',
-'undo-norev' => 'ఈ దిద్దుబాటును అసలు లేకపోవటం వలన, లేదా తొలగించేయడం వలన రద్దుచేయలేకపోతున్నాం.',
-'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|à°\9aà°°à±\8dà°\9a]]) à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\87సిన à°\95à±\82à°°à±\8dà°ªà±\81 $1 à°¨à±\81 à°°à°¦à±\8dà°¦à±\81 à°\9aà±\87సారà±\81',
+'undo-norev' => 'ఈ దిద్దుబాటు అసలు లేకపోవటం వలన గానీ, లేదా తొలగించేయడం వలన గానీ దాన్ని రద్దుచేయలేకపోతున్నాం.',
+'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|à°\9aà°°à±\8dà°\9a]]) à°¯à±\8aà°\95à±\8dà°\95 à°\95à±\82à°°à±\8dà°ªà±\81 $1 à°¨à±\81 à°°à°¦à±\8dà°¦à±\81à°\9aà±\86à°¯à±\8dయి',
 'undo-summary-username-hidden' => 'దాచబడిన వాడుకరి చేసిన కూర్పు $1 ని వెనక్కి తిప్పండి',
 
 # Account creation failure
@@ -1022,26 +1027,26 @@ $3 ఇచ్చిన కారణం: ''$2''",
 'revisionasof' => '$1 నాటి కూర్పు',
 'revision-info' => '$1 నాటి కూర్పు. రచయిత: $2',
 'previousrevision' => '← పాత కూర్పు',
-'nextrevision' => 'à°¦à±\80ని à°¤à°°à±\81వాతి à°¸à°\82à°\9aà°¿à°\95→',
-'currentrevisionlink' => 'ప్రస్తుతపు సంచిక',
+'nextrevision' => 'తరà±\81వాతి à°\95à±\82à°°à±\8dà°ªà±\81 →',
+'currentrevisionlink' => 'ప్రస్తుత కూర్పు',
 'cur' => 'ప్రస్తుత',
-'next' => 'తరà±\8dవాతి',
+'next' => 'తరà±\81వాతి',
 'last' => 'గత',
 'page_first' => 'మొదటి',
 'page_last' => 'చివరి',
 'histlegend' => 'తేడా ఎంపిక: సంచికల యొక్క రేడియో బాక్సులను ఎంచుకొని ఎంటర్‌ నొక్కండి, లేదా పైన/ కింద ఉన్న మీటను నొక్కండి.<br />
-సూచిక: (ప్రస్తుత) = ప్రస్తుత సంచికతో కల తేడాలు, (గత) = ఇంతకు ముందరి సంచికతో గల తేడాలు, చి = చిన్న మార్పు',
-'history-fieldset-title' => 'చరిత్రలో చూడండి',
+సూచిక: <strong>({{int:cur}})</strong> = ప్రస్తుత సంచికతో కల తేడాలు, <strong>({{int:last}})</strong> = ఇంతకు ముందరి సంచికతో గల తేడాలు, <strong>{{int:minoreditletter}}</strong> = చిన్న మార్పు',
+'history-fieldset-title' => 'చరిత్ర చూడండి',
 'history-show-deleted' => 'తొలగించినవి మాత్రమే',
-'histfirst' => 'à°¤à±\8aà°\9fà±\8dà°\9fà°¤à±\8aà°²ి',
-'histlast' => 'à°\9aà°¿à°\9fà±\8dà°\9fà°\9aివరి',
+'histfirst' => 'à°\85తి à°ªà°¾à°¤à°µి',
+'histlast' => 'సరిà°\95à±\8aà°¤à±\8dà°¤',
 'historysize' => '({{PLURAL:$1|ఒక బైటు|$1 బైట్లు}})',
 'historyempty' => '(ఖాళీ)',
 
 # Revision feed
 'history-feed-title' => 'కూర్పుల చరిత్ర',
 'history-feed-description' => 'ఈ పేజీకి వికీలో కూర్పుల చరిత్ర',
-'history-feed-item-nocomment' => '$2 à°µà°¦à±\8dà°¦ à°\89à°¨à±\8dà°¨ $1',
+'history-feed-item-nocomment' => '$2 న $1',
 'history-feed-empty' => 'మీరడిగిన పేజీ లేదు.
 దాన్ని వికీలోంచి తొలగించి ఉండొచ్చు, లేదా పేరు మార్చి ఉండొచ్చు.
 సంబంధిత కొత్త పేజీల కోసం [[Special:Search|వికీలో వెతికి చూడండి]].',
@@ -1051,8 +1056,8 @@ $3 ఇచ్చిన కారణం: ''$2''",
 'rev-deleted-user' => '(వాడుకరి పేరుని తొలగించారు)',
 'rev-deleted-event' => '(దినచర్యని తొలగించాం)',
 'rev-deleted-user-contribs' => '[వాడుకరిపేరు లేదా ఐపీ చిరునామాని తొలగించారు  - మార్పుచేర్పుల నుండి మార్పుని దాచారు]',
-'rev-deleted-text-permission' => "ఈ పేజీ కూర్పుని '''తొలగించారు'''.
-[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à°¤à±\8aà°²à°\97à°¿à°\82à°ªà±\81 à°\9aà°¿à°\9fà±\8dà°\9fà°¾]à°²à±\8b à°ªà±\82à°°à±\8dతి à°µà°¿à°µà°°à°¾à°²à±\81 à°\89à°\82à°¡à°µà°\9aà±\8dà°\9aà±\81.",
+'rev-deleted-text-permission' => 'ఈ పేజీ కూర్పుని <strong>తొలగించారు</strong>.
+[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à°¤à±\8aà°²à°\97à°¿à°\82à°ªà±\81 à°\9aà°¿à°\9fà±\8dà°\9fà°¾]à°²à±\8b à°ªà±\82à°°à±\8dతి à°µà°¿à°µà°°à°¾à°²à±\81 à°\9aà±\82à°¡à°µà°\9aà±\8dà°\9aà±\81.',
 'rev-deleted-text-unhide' => "పేజీ యొక్క ఈ కూర్పును '''తొలగించాం'''.
 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు చిట్టా]లో వివరాలు చూడవచ్చు.
 మీరు కావాలనుకుంటే, [$1 ఈ కూర్పుని చూడవచ్చు].",
@@ -1063,8 +1068,8 @@ $3 ఇచ్చిన కారణం: ''$2''",
 మీరు దాన్ని చూడవచ్చు; [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు చిట్టా]లో వివరాలు దొరుకుతాయి.',
 'rev-suppressed-text-view' => 'ఈ పేజీకూర్పును <strong>అణచి పెట్టాం</strong>.
 మీరు దాన్ని చూడవచ్చు; [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} అణచివేత చిట్టా]లోవివరాలు ఉంటాయి.',
-'rev-deleted-no-diff' => "మీరు తేడాలను చూడలేదు ఎందుకంటే ఒక కూర్పుని '''తొలగించారు'''.
-[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à°¤à±\8aà°²à°\97à°¿à°\82à°ªà±\81 à°\9aà°¿à°\9fà±\8dà°\9fà°¾]à°²à±\8b à°µà°¿à°µà°°à°¾à°²à±\81 à°\89à°\82à°¡à°µà°\9aà±\8dà°\9aà±\81.",
+'rev-deleted-no-diff' => 'మీరు ఈ తేడాను చూడలేరు. ఎందుకంటే ఒక కూర్పు <strong>తొలగించబడింది</strong>.
+[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} à°¤à±\8aà°²à°\97à°¿à°\82à°ªà±\81 à°\9aà°¿à°\9fà±\8dà°\9fà°¾]à°²à±\8b à°µà°¿à°µà°°à°¾à°²à±\81 à°\9aà±\82à°¡à°µà°\9aà±\8dà°\9aà±\81.',
 'rev-suppressed-no-diff' => "ఈ తేడాని మీరు చూడలేరు ఎందుకంటే ఒక కూర్పుని '''తొలగించారు'''.",
 'rev-deleted-unhide-diff' => 'ఈ తేడాల యొక్క కూర్పులలో ఒకదాన్ని <strong>తొలగించారు</strong>.
 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు చిట్టా]లో వివరాలు ఉంటాయి.
@@ -1076,29 +1081,29 @@ $3 ఇచ్చిన కారణం: ''$2''",
 మీరు ఈ తేడాను చూడవచ్చు; [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} తొలగింపు చిట్టా]లోవివరాలు ఉంటాయి.',
 'rev-suppressed-diff-view' => 'ఈ తేడా లోని ఒక కూర్పును <strong>అణచి పెట్టాం</strong>.
 మీరు ఈ తేడాను చూడవచ్చు; [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} అణచివేత చిట్టా]లోవివరాలు ఉంటాయి.',
-'rev-delundel' => 'à°\9aà±\82పిà°\82à°\9aà±\81/దాచు',
+'rev-delundel' => 'à°¦à±\83à°¶à±\8dయతనà±\81 à°®à°¾à°°à±\8dచు',
 'rev-showdeleted' => 'చూపించు',
 'revisiondelete' => 'కూర్పులను తొలగించు/తొలగింపును రద్దుచెయ్యి',
 'revdelete-nooldid-title' => 'తప్పుడు లక్ష్యపు కూర్పు',
 'revdelete-nooldid-text' => 'ఈ పని ఏ కూర్పు లేదా కూర్పుల మీద చెయ్యాలో మీరు సూచించలేదు, లేదా మీరు సూచించిన కూర్పు లేదు, లేదా ప్రస్తుత కూర్పునే దాచాలని ప్రయత్నిస్తున్నారు.',
-'revdelete-no-file' => 'à°\86 à°ªà±\87à°°à±\8dà°\95à±\8aà°¨à±\8dà°¨ à°«à±\88à°²à±\81 à°\89నిà°\95à°¿à°²à±\8b à°²à±\87à°¦à±\81.',
+'revdelete-no-file' => 'పేర్కొన్న ఫైలు ఉనికిలో లేదు.',
 'revdelete-show-file-confirm' => 'మీరు నిజంగానే "<nowiki>$1</nowiki>"  ఫైలు యొక్క $2 $3 నాటి తొలగించిన కూర్పుని చూడాలనుకుంటున్నారా?',
 'revdelete-show-file-submit' => 'అవును',
-'revdelete-selected' => "'''[[:$1]] యొక్క {{PLURAL:$2|ఎంచుకున్న కూర్పు|ఎంచుకున్న కూర్పులు}}:'''",
-'logdelete-selected' => "'''{{PLURAL:$1|ఎంచుకున్న చిట్టా ఘటన|ఎంచుకున్న చిట్టా ఘటనలు}}:'''",
+'revdelete-selected' => '<strong>[[:$1]] యొక్క {{PLURAL:$2|ఎంచుకున్న కూర్పు|ఎంచుకున్న కూర్పులు}}:</strong>',
+'logdelete-selected' => '<strong>{{PLURAL:$1|ఎంచుకున్న చిట్టా ఘటన|ఎంచుకున్న చిట్టా ఘటనలు}}:</strong>',
 'revdelete-text' => "'''తొలగించిన కూర్పులు, ఘటనలూ పేజీ చరితం లోనూ, చిట్టాలలోనూ కనిపిస్తాయి, కానీ వాటిలో కొన్ని భాగాలు సార్వజనికంగా అందుబాటులో ఉండవు.'''
 {{SITENAME}} లోని ఇతర నిర్వాహకులు ఆ దాచిన భాగాలను చూడగలరు మరియు (ఏవిధమైన నియంత్రణలూ లేకుంటే) ఇదే అంతరవర్తి ద్వారా వాటిని పునస్థాపించగలరు.",
-'revdelete-confirm' => 'à°®à±\80à°°à±\81 à°¦à±\80à°¨à±\8dని à°\9aà±\87à°¯à°\97à±\8bà°°à±\81à°¤à±\81à°¨à±\8dనారనà±\80, à°¦à±\80ని à°ªà°°à±\8dయవసానాలà±\81 à°®à±\80à°\95à±\81 à°¤à±\86à°²à±\81à°¸à±\81ననà±\80, à°®à°°à°¿à°¯à±\81 à°®à±\80à°°à±\81 à°¦à±\80à°¨à±\8dని [[{{MediaWiki:Policy-url}}|విధానà°\82]] à°ªà±\8dà°°à°\95ారమà±\87 à°\9aà±\87à°¸à±\8dà°¤à±\81à°¨à±\8dనారనà±\80 à°¦à°¯à°\9aà±\87సి నిర్ధారించండి.',
+'revdelete-confirm' => 'à°®à±\80à°°à±\81 à°¦à±\80à°¨à±\8dని à°\9aà±\87à°¯à°\97à±\8bà°°à±\81à°¤à±\81à°¨à±\8dనారనà±\80, à°¦à±\80ని à°ªà°°à±\8dయవసానాలà±\81 à°®à±\80à°\95à±\81 à°¤à±\86à°²à±\81à°¸à±\81ననà±\80, à°¦à±\80à°¨à±\8dని à°¸à°\82à°¬à°\82ధిత [[{{MediaWiki:Policy-url}}|విధానà°\82]] à°ªà±\8dà°°à°\95ారమà±\87 à°\9aà±\87à°¸à±\8dà°¤à±\81à°¨à±\8dనారనà±\80 నిర్ధారించండి.',
 'revdelete-suppress-text' => 'అణచివేతను కింది సందర్భాలలో <strong>మాత్రమే</strong> వాడాలి:
 * బురదజల్లే ధోరణిలో ఉన్న సమాచారం
 * అనుచితమైన వ్యక్తిగత సమాచారం
 *<em>ఇంటి చిరునామాలు, టెలిఫోను నంబర్లు, జాతీయ ఐడీ నంబర్లు, వగైరాలు</em>',
 'revdelete-legend' => 'సందర్శక నిబంధనలు అమర్చు',
-'revdelete-hide-text' => 'à°ªà±\81à°¨à°\83పరిశà±\80లన పాఠ్యం',
+'revdelete-hide-text' => 'à°\95à±\82à°°à±\8dà°ªà±\81 పాఠ్యం',
 'revdelete-hide-image' => 'ఫైలులోని విషయాన్ని దాచు',
 'revdelete-hide-name' => 'చర్యను, లక్ష్యాన్నీ దాచు',
 'revdelete-hide-comment' => 'దిద్దుబాటు సారాంశం',
-'revdelete-hide-user' => 'దిద్దుబాటు చేసినవారి వాడుకరి పేరు/ఐపీ చిరునామా',
+'revdelete-hide-user' => 'దిద్దుబాటు చేసిన వాడుకరి పేరు/ఐపీ చిరునామా',
 'revdelete-hide-restricted' => 'డేటాను అందరిలాగే నిర్వాహకులకు కూడా కనబడనివ్వకు',
 'revdelete-radio-same' => '(మార్చకు)',
 'revdelete-radio-set' => 'దాచు',
@@ -1107,10 +1112,10 @@ $3 ఇచ్చిన కారణం: ''$2''",
 'revdelete-unsuppress' => 'పునస్థాపిత కూర్పులపై నిబంధనలను తీసివెయ్యి',
 'revdelete-log' => 'కారణం:',
 'revdelete-submit' => 'ఎంచుకున్న {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} ఆపాదించు',
-'revdelete-success' => "'''కూర్పు కనబడే విధానాన్ని జయప్రదంగా తాజాకరించాం.'''",
-'revdelete-failure' => "'''కూర్పు కనబడే పద్ధతిని తాజాపరచలేకపోయాం:'''
-$1",
-'logdelete-success' => "'''ఘటన కనబడే విధానాన్ని జయప్రదంగా సెట్ చేసాం.'''",
+'revdelete-success' => '<strong>కూర్పు కనబడే విధానాన్ని జయప్రదంగా తాజాకరించాం.</strong>',
+'revdelete-failure' => '<strong>కూర్పు కనబడే పద్ధతిని తాజాపరచలేకపోయాం:</strong>
+$1',
+'logdelete-success' => '<strong>ఘటన కనబడే విధానాన్ని జయప్రదంగా సెట్ చేసాం.</strong>',
 'logdelete-failure' => "'''చిట్టా కనబడే పద్ధతిని అమర్చలేకపోయాం:'''
 $1",
 'revdel-restore' => 'దృశ్యతని మార్చు',
@@ -1172,7 +1177,7 @@ $1",
 
 # Diffs
 'history-title' => '"$1" యొక్క కూర్పుల చరిత్ర',
-'difference-title' => '"$1" à°¯à±\8aà°\95à±\8dà°\95 à°¤à°¿à°°à°¿à°\97à°¿à°\9aà±\82à°ªà±\81à°² à°¨à°¡à±\81à°® తేడాలు',
+'difference-title' => '"$1" à°¯à±\8aà°\95à±\8dà°\95 à°\95à±\82à°°à±\8dà°ªà±\81à°² à°®à°§à±\8dà°¯ తేడాలు',
 'difference-title-multipage' => '"$1" మరియు "$2" పేజీల మధ్య తేడా',
 'difference-multipage' => '(పేజీల మధ్య తేడా)',
 'lineno' => 'పంక్తి $1:',
@@ -1182,7 +1187,7 @@ $1",
 'diff-empty' => '(తేడా లేదు)',
 'diff-multi-sameuser' => '(ఇదే వాడుకరి యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించలేదు)',
 'diff-multi-otherusers' => '({{PLURAL:$2|మరో వాడుకరి|$2 వాడుకరుల}} యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించలేదు)',
-'diff-multi-manyusers' => '$2 à°®à°\82ది à°ªà±\88à°¨ ({{PLURAL:$2|ఒక వాడుకరి|వాడుకరుల}} యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించట్లేదు)',
+'diff-multi-manyusers' => '$2 à°\95à°\82à°\9fà±\87 à°\8eà°\95à±\8dà°\95à±\81à°µ ({{PLURAL:$2|ఒక వాడుకరి|వాడుకరుల}} యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించట్లేదు)',
 'difference-missing-revision' => 'ఈ తేడా ($1) యొక్క {{PLURAL:$2|ఒక కూర్పు|$2 కూర్పులు}} {{PLURAL:$2|కనబడలేదు}}.
 
 సాధారణంగా, తొలగించబడిన పేజీ యొక్క కాలం చెల్లిన ’తేడా’ లింకును నొక్కినపుడు ఇది జరుగుతుంది. 
@@ -1191,7 +1196,7 @@ $1",
 # Search results
 'searchresults' => 'వెతుకులాట ఫలితాలు',
 'searchresults-title' => '"$1" కి వెతుకులాట ఫలితాలు',
-'toomanymatches' => 'à°\9aాలా పోలికలు వచ్చాయి, దయచేసి మరో ప్రశ్నని ప్రయత్నించండి',
+'toomanymatches' => 'మరà±\80 à°\8eà°\95à±\8dà°\95à±\81à°µ పోలికలు వచ్చాయి, దయచేసి మరో ప్రశ్నని ప్రయత్నించండి',
 'titlematches' => 'వ్యాస శీర్షిక సరిపోయింది',
 'textmatches' => 'పేజిలోని పాఠం సరిపోలింది',
 'notextmatches' => 'పేజీ పాఠ్యమేదీ సరిపోలడం లేదు',
@@ -1201,7 +1206,7 @@ $1",
 'nextn-title' => 'తరువాతి $1 {{PLURAL:$1|ఫలితం|ఫలితాలు}}',
 'shown-title' => 'పేజీకి $1 {{PLURAL:$1|ఫలితాన్ని|ఫలితాలను}} చూపించు',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) చూపించు.',
-'searchmenu-exists' => "'''ఈ వికీలో \"[[:\$1]]\" అనే పేజీ ఉంది'''",
+'searchmenu-exists' => '<strong>ఈ వికీలో "[[:$1]]" అనే పేజీ ఉంది.</strong> {{PLURAL:$2|0=|ఇతర ఫలితాలను కూడా చూడండి.}}',
 'searchmenu-new' => '<strong>ఈ వికీలో "[[:$1]]" అనే పేరుతో పేజీని సృష్టించండి!</strong> {{PLURAL:$2|0=|మీ వెతుకులాటలో దొరికిన పేజీని కూడా చూడండి.|వెతుకులాట ఫలితాలను కూడా చూడండి.}}',
 'searchprofile-articles' => 'విషయపు పేజీలు',
 'searchprofile-project' => 'సహాయం మరియు ప్రాజెక్టు పేజీలు',
@@ -1227,8 +1232,8 @@ $1",
 'searcheverything-enable' => 'అన్ని పేరుబరుల్లో వెతుకు',
 'searchrelated' => 'సంబంధించినవి',
 'searchall' => 'అన్నీ',
-'showingresults' => "కింద ఉన్న {{PLURAL:$1|'''ఒక్క''' ఫలితం|'''$1''' ఫలితాలు}}, #'''$2''' నుండి మొదలుకొని చూపిస్తున్నాం.",
-'showingresultsnum' => "కింద ఉన్న {{PLURAL:$3|'''ఒక్క''' ఫలితం|'''$3''' ఫలితాలు}}, #'''$2''' నుండి మొదలుకొని చూపిస్తున్నాం.",
+'showingresults' => '#<strong>$2</strong> నుండి మొదలుకొని {{PLURAL:$1|</strong>ఒక్క</strong> ఫలితాన్ని|<strong>$1</strong> ఫలితాలను}} కింద చూపించాం.',
+'showingresultsnum' => '#<strong>$2</strong> నుండి మొదలుకొని {{PLURAL:$3|<strong>ఒక్క</strong> ఫలితాన్ని|<strong>$3</strong> ఫలితాలను}} కింద చూపించాం.',
 'showingresultsheader' => "'''$4''' కొరకై {{PLURAL:$5|'''$3'''లో '''$1''' ఫలితం|'''$3''' ఫలితాల్లో '''$1 - $2''' వరకు}}",
 'search-nonefound' => 'మీ ప్రశ్నకి సరిపోలిన ఫలితాలేమీ లేవు.',
 'powersearch-legend' => 'నిశితమైన అన్వేషణ',
@@ -1238,7 +1243,7 @@ $1",
 'powersearch-toggleall' => 'అన్నీ',
 'powersearch-togglenone' => 'ఏదీకాదు',
 'search-external' => 'బయటి అన్వేషణ',
-'searchdisabled' => '{{SITENAME}} à°\85à°¨à±\8dà°µà±\87à°·à°£ à°¤à°¾à°¤à±\8dà°\95ాలిà°\95à°\82à°\97à°¾ à°ªà°¨à°¿ à°\9aà±\86à°¯à±\8dయడà°\82 à°²à±\87à°¦à±\81. à°\88à°²à±\8bà°\97à°¾ à°®à±\80à°°à±\81 à°\97à±\82à°\97à±\81à°²à±\8dâ\80\8c à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¿ à°\85à°¨à±\8dà°µà±\87à°·à°¿à°\82à°\9aà°µà°\9aà±\8dà°\9aà±\81. à°\92à°\95 à°\97మనిà°\95: à°\97à±\82à°\97à±\81à°²à±\8dâ\80\8c à°¦à±\8dవారా à°\95ాలదà±\8bà°·à°\82 à°ªà°\9fà±\8dà°\9fà°¿à°¨ à°«à°²à°¿à°¤à°¾à°²à±\81 à°°à°¾à°µà°¡à°¾à°¨à°¿à°\95à°¿ అవకాశం ఉంది.',
+'searchdisabled' => '{{SITENAME}} à°\85à°¨à±\8dà°µà±\87à°·à°£ à°¤à°¾à°¤à±\8dà°\95ాలిà°\95à°\82à°\97à°¾ à°ªà°¨à°¿ à°\9aà±\86à°¯à±\8dయడà°\82 à°²à±\87à°¦à±\81. à°\88à°²à±\8bà°\97à°¾ à°®à±\80à°°à±\81 à°\97à±\82à°\97à±\81à°²à±\8dâ\80\8c à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¿ à°\85à°¨à±\8dà°µà±\87à°·à°¿à°\82à°\9aà°µà°\9aà±\8dà°\9aà±\81. à°\97మనిà°\95: à°\97à±\82à°\97à±\81à°²à±\8dâ\80\8c à°µà°¾à°°à°¿ {{SITENAME}} à°«à°²à°¿à°¤à°¾à°²à±\81 à°\95ాలదà±\8bà°·à°\82 à°ªà°\9fà±\8dà°\9fà°¿ à°\89à°\82à°¡à±\87 అవకాశం ఉంది.',
 'search-error' => '$1 కోసం వెతికేటపుడు లోపమేదో దొర్లింది.',
 
 # Preferences page
@@ -1264,19 +1269,19 @@ $1",
 'prefs-misc' => 'ఇతరత్రా',
 'prefs-resetpass' => 'సంకేతపదాన్ని మార్చుకోండి',
 'prefs-changeemail' => 'ఈ-మెయిలు చిరునామా మార్పు',
-'prefs-setemail' => 'à°\92à°\95 à°\88-à°®à±\86యిలà±\8d à°\9aà°¿à°°à±\81నామాని à°\85మరà±\8dà°\9aండి',
+'prefs-setemail' => 'à°\93 à°\88à°®à±\86యిలà±\8d à°\9aà°¿à°°à±\81నామా à°\87à°µà±\8dà°µండి',
 'prefs-email' => 'ఈ-మెయిల్ ఎంపికలు',
 'prefs-rendering' => 'రూపురేఖలు',
 'saveprefs' => 'భద్రపరచు',
 'restoreprefs' => 'అప్రమేయ అమరికలను పునఃస్థాపించు (అన్ని విభాగాల్లోనూ)',
-'prefs-editing' => 'మారà±\8dà°ªà±\81à°²ు',
+'prefs-editing' => 'సవరిసà±\8dà°¤à±\81à°¨à±\8dనారు',
 'rows' => 'అడ్డు వరుసలు:',
 'columns' => 'నిలువు వరుసలు:',
 'searchresultshead' => 'వెతుకు',
 'stub-threshold' => '<a href="#" class="stub">మొలక లింకు</a> ఫార్మాటింగు కొరకు హద్దు (బైట్లు):',
 'stub-threshold-disabled' => 'అచేతనం',
 'recentchangesdays' => 'ఇటీవలి మార్పులు లో చూపించవలసిన రోజులు:',
-'recentchangesdays-max' => '($1 {{PLURAL:$1|రోజు|రోజులు}} గరిష్ఠం)',
+'recentchangesdays-max' => 'గరిష్ఠంగా $1 {{PLURAL:$1|రోజు|రోజులు}}',
 'recentchangescount' => 'అప్రమేయంగా చూపించాల్సిన దిద్దుబాట్ల సంఖ్య:',
 'prefs-help-recentchangescount' => 'ఇది ఇటీవలి మార్పులు, పేజీ చరిత్రలు, మరియు చిట్టాలకు వర్తిస్తుంది.',
 'prefs-help-watchlist-token2' => 'మీ వీక్షణజాబితా యొక్క జాలవడ్డింపుకు చెందిన రహస్య తాళమిది.
@@ -1307,7 +1312,7 @@ $1",
 'prefs-files' => 'ఫైళ్ళు',
 'prefs-custom-css' => 'ప్రత్యేక CSS',
 'prefs-custom-js' => 'ప్రత్యేక JS',
-'prefs-common-css-js' => 'à°\85à°¨à±\8dని à°\85à°²à°\82à°\95ారాలà°\95à±\88 à°ªà°\82à°\9aà±\81à°\95à±\8bబడిన CSS/JS:',
+'prefs-common-css-js' => 'à°\85à°¨à±\8dని à°°à±\82à°ªà±\81లలà±\8bà°¨à±\82 à°\89à°¨à±\8dన CSS/JS:',
 'prefs-reset-intro' => 'ఈ పేజీలో, మీ అభిరుచులను సైటు డిఫాల్టు విలువలకు మార్చుకోవచ్చు. మళ్ళీ వెనక్కి తీసుకుపోలేరు.',
 'prefs-emailconfirm-label' => 'ఈ-మెయిల్ నిర్ధారణ:',
 'youremail' => 'ఈమెయిలు:',
@@ -1319,9 +1324,10 @@ $1",
 'yourlanguage' => 'భాష:',
 'yourvariant' => 'విషయపు భాషా వైవిధ్యం:',
 'prefs-help-variant' => 'ఈ వికీ లోని విషయపు పేజీలను చూపించడానికి మీ అభిమత వైవిధ్యం లేదా ఆర్ధోగ్రఫీ.',
-'yournick' => 'à°®à±\81à°¦à±\8dà°¦à±\81 à°ªà±\87à°°à±\81',
+'yournick' => 'à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°¤à°\95à°\82:',
 'prefs-help-signature' => 'చర్చా పేజీల లోని వ్యాఖ్యలకు "<nowiki>~~~~</nowiki>"తో సంతకం చేస్తే అది మీ సంతకం మరియు కాలముద్రగా మారుతుంది.',
-'badsig' => 'సంతకాన్ని సరిగ్గా ఇవ్వలేదు; HTML ట్యాగులను ఒకసారి పరిశీలించండి.',
+'badsig' => 'సంతకం చెల్లనిది.
+HTML ట్యాగులను ఒకసారి సరిచూసుకోండి.',
 'badsiglength' => 'మీ సంతకం చాలా పెద్దగా ఉంది.
 ఇది తప్పనిసరిగా $1 {{PLURAL:$1|అక్షరం|అక్షరాల}} లోపులోనే ఉండాలి.',
 'yourgender' => 'మిమ్మల్ని మీరు ఎలా వర్ణించుకుంటారు?',
@@ -1332,8 +1338,9 @@ $1",
 మిమ్మల్ని సంబోధించేప్పుడూ మిమ్మల్ని పేర్కొనేప్పుడూ వ్యాకరణపరంగా సరైన లింగాన్ని  వాడటానికి ఈ విలువ ఉపయోగపడుతుంది.
 ఈ సమాచారం బహిరంగం.',
 'email' => 'ఈ-మెయిలు',
-'prefs-help-realname' => 'అసలు పేరు (తప్పనిసరి కాదు), మీ అసలు పేరు ఇస్తేగనక, మీ రచనలన్నీ మీ అసలు పేరుతోనే గుర్తిస్తూ ఉంటారు.',
-'prefs-help-email' => 'ఈ-మెయిలు చిరునామా ఐచ్చికం, కానీ మీరు సంకేతపదాన్ని మర్చిపోతే కొత్త సంకేతపదాన్ని మీకు పంపించడానికి అవసరమవుతుంది.',
+'prefs-help-realname' => 'అసలు పేరు తప్పనిసరి కాదు. 
+అసలు పేరు ఇస్తే, మీ రచనల శ్రేయస్సు మీ అసలు పేరుకే ఆపాదించబడుతుంది.',
+'prefs-help-email' => 'ఈమెయిలు చిరునామా ఐచ్చికం. కానీ మీరు సంకేతపదాన్ని మర్చిపోతే కొత్త సంకేతపదాన్ని మీకు పంపించడానికి ఇది అవసరం.',
 'prefs-help-email-others' => 'మీ వాడుకరి లేదా చర్చా పేజీలలో ఉండే లంకె ద్వారా ఇతరులు మిమ్మల్ని ఈ-మెయిలు ద్వారా సంప్రదించే వీలుకల్పించవచ్చు.
 ఇతరులు మిమ్మల్ని సంప్రదించినప్పుడు మీ ఈ-మెయిలు చిరునామా బహిర్గతమవదు.',
 'prefs-help-email-required' => 'ఈ-మెయిలు చిరునామా తప్పనిసరి.',
@@ -1341,9 +1348,9 @@ $1",
 'prefs-i18n' => 'అంతర్జాతీయకరణ',
 'prefs-signature' => 'సంతకం',
 'prefs-dateformat' => 'తేదీ ఆకృతి',
-'prefs-timeoffset' => 'సమయ సవరణ',
+'prefs-timeoffset' => 'సమయపు తేడా',
 'prefs-advancedediting' => 'సాధారణ ఎంపికలు',
-'prefs-editor' => 'à°\95à±\82à°°à±\8dపరి',
+'prefs-editor' => 'à°°à°\9aయిత',
 'prefs-preview' => 'మునుజూపు',
 'prefs-advancedrc' => 'ఉన్నత ఎంపికలు',
 'prefs-advancedrendering' => 'ఉన్నత ఎంపికలు',
@@ -1363,22 +1370,22 @@ $1",
 
 # User rights
 'userrights' => 'వాడుకరి హక్కుల నిర్వహణ',
-'userrights-lookup-user' => 'వాడà±\81à°\95à°°à°¿ à°¸à°®à±\82హాలనà±\81 à°¸à°\82భాళించండి',
-'userrights-user-editname' => 'సభà±\8dయనామానà±\8dని ఇవ్వండి:',
+'userrights-lookup-user' => 'వాడà±\81à°\95à°°à°¿ à°¸à°®à±\82హాలనà±\81 à°¨à°¿à°°à±\8dవహించండి',
+'userrights-user-editname' => 'వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\81à°¨à±\81 ఇవ్వండి:',
 'editusergroup' => 'వాడుకరి గుంపులను మార్చు',
 'editinguser' => "వాడుకరి '''[[User:$1|$1]]''' $2 యొక్క వాడుకరి హక్కులను మారుస్తున్నారు",
 'userrights-editusergroup' => 'వాడుకరి సమూహాలను మార్చండి',
 'saveusergroups' => 'వాడుకరి గుంపులను భద్రపరచు',
 'userrights-groupsmember' => 'సభ్యులు:',
 'userrights-groupsmember-auto' => 'సంభావిత సభ్యులు:',
-'userrights-groups-help' => 'à°\88 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\8fà°¯à±\87 à°\97à±\81à°\82à°ªà±\81లలà±\8b à°\89à°\82à°¡à°µà°\9aà±\8dà°\9aో మీరు మార్చవచ్చు.
+'userrights-groups-help' => 'à°\88 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\8fà°¯à±\87 à°\97à±\81à°\82à°ªà±\81లలà±\8b à°\89à°\82డాలో మీరు మార్చవచ్చు.
 * టిక్కు పెట్టివుంటే ఆ గుంపులో ఈ వాడుకరి ఉన్నట్టు.
 * టిక్కు లేకుంటే ఆ గుంపులో ఈ వాడుకరి లేనట్టు.
-* <nowiki>*</nowiki> ఉంటే ఒకసారి ఆ గుంపుని చేర్చాకా మీరు తీసివేయలేరు, లేదా తీసివేసాకా తిరిగి చేర్చలేరు.',
+* * ఉంటే ఒకసారి ఆ గుంపుని చేర్చాక మీరు తీసివేయలేరు, లేదా తీసివేసాక తిరిగి చేర్చలేరు.',
 'userrights-reason' => 'కారణం:',
 'userrights-no-interwiki' => 'ఇతర వికీలలో వాడుకరి హక్కులను మార్చడానికి మీకు అనుమతి లేదు.',
 'userrights-nodatabase' => '$1 అనే డేటాబేసు లేదు లేదా అది స్థానికం కాదు.',
-'userrights-nologin' => 'వాడà±\81à°\95à°°à°¿ à°¹à°\95à±\8dà°\95à±\81లనà±\81 à°\87à°µà±\8dవడానిà°\95à°¿ à°®à±\80à°°à±\81 à°¤à°ªà±\8dపనిసరిà°\97à°¾ à°\93 à°¨à°¿à°°à±\8dవాహà°\95 à°\96ాతాతà±\8b [[Special:UserLogin|à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aాలి]].',
+'userrights-nologin' => 'వాడà±\81à°\95à°°à°¿ à°¹à°\95à±\8dà°\95à±\81లనà±\81 à°\87à°µà±\8dవడానిà°\95à°¿ à°®à±\80à°°à±\81 à°¤à°ªà±\8dపనిసరిà°\97à°¾ à°\93 à°¨à°¿à°°à±\8dవాహà°\95 à°\96ాతాతà±\8b [[Special:UserLogin|లాà°\97ినవà±\8dà°µాలి]].',
 'userrights-notallowed' => 'వాడుకరి హక్కులను చేర్చే మరియు తొలగించే అనుమతి మీకు లేదు.',
 'userrights-changeable-col' => 'మీరు మార్చదగిన గుంపులు',
 'userrights-unchangeable-col' => 'మీరు మార్చలేని గుంపులు',
@@ -1406,7 +1413,7 @@ $1",
 'grouppage-autoconfirmed' => '{{ns:project}}:ఆటోమాటిగ్గా నిర్ధారించబడిన వాడుకరులు',
 'grouppage-bot' => '{{ns:project}}:బాట్లు',
 'grouppage-sysop' => '{{ns:project}}:నిర్వాహకులు',
-'grouppage-bureaucrat' => '{{ns:project}}:à°\85ధిà°\95ారà±\8dలు',
+'grouppage-bureaucrat' => '{{ns:project}}:à°\85ధిà°\95ారà±\81లు',
 'grouppage-suppress' => '{{ns:project}}:పూర్తి తొలగింపు',
 
 # Rights
@@ -1425,19 +1432,19 @@ $1",
 'right-reupload' => 'ఇప్పటికే ఉన్న ఫైలును తిరగరాయి',
 'right-reupload-own' => 'తానే ఇదివరలో అప్‌లోడు చేసిన ఫైలును తిరగరాయి',
 'right-reupload-shared' => 'స్థానికంగా ఉమ్మడి మీడియా సొరుగులోని ఫైళ్ళను అధిక్రమించు',
-'right-upload_by_url' => 'URL à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81à°\82à°¡à°¿ à°«à±\88à°²à±\81à°¨à±\81 à°\85à°ªà±\8dâ\80\8cà°²à±\8bà°¡à±\81 à°\9aà±\86à°¯à±\8dయి',
+'right-upload_by_url' => 'URL à°\85à°¡à±\8dà°°à°¸à±\81à°¨à±\81à°\82à°¡à°¿ à°«à±\88à°²à±\81à°¨à±\81 à°\85à°ªà±\8dâ\80\8cà°²à±\8bà°¡à±\81 à°\9aà±\86à°¯à±\8dయడà°\82',
 'right-purge' => 'పేజీకి సంబంధించిన సైటు కాషెను, నిర్ధారణ కోరకుండానే తొలగించు',
 'right-autoconfirmed' => 'ఐపీ ఆధారిత రేటు పరిమితులు ప్రభావం చూపవు',
 'right-bot' => 'ఆటోమాటిక్ ప్రాసెస్ లాగా భావించబడు',
-'right-nominornewtalk' => 'à°\9aà°°à±\8dà°\9aà°¾ à°ªà±\87à°\9cà±\80à°²à±\8dà°²à±\8b à°\9cà°°à°¿à°\97à°¿à°¨ à°\85తి à°\9aà°¿à°¨à±\8dà°¨ à°®à°¾à°°à±\8dà°ªà±\81à°²à°\95à±\81 à°\95à±\8aà°¤à±\8dతసà°\82à°¦à±\87శమà±\81 à°µà°\9aà±\8dà°\9aà°¿à°\82దనà±\8dà°¨ à°¸à±\82à°\9aà°¨ à°\9aà±\86à°¯à±\8dయవదà±\8dదు',
-'right-apihighlimits' => 'API à°ªà±\8dà°°à°¶à±\8dనలà±\8dà°²à±\8b à°\89à°¨à±\8dనత à°ªà°°à°¿à°®à°¿à°¤à±\81లనà±\81 à°µà°¾à°¡à±\81',
+'right-nominornewtalk' => 'à°\9aà°°à±\8dà°\9aà°¾ à°ªà±\87à°\9cà±\80à°²à±\8dà°²à±\8b à°\9aà±\87à°¸à±\87 à°\9aà°¿à°¨à±\8dà°¨ à°®à°¾à°°à±\8dà°ªà±\81à°²à°\95à±\81 à°\95à±\8aà°¤à±\8dతసà°\82à°¦à±\87శపà±\81 à°¸à±\82à°\9aà°¨ à°ªà°\82à°ªà°\95à±\82à°¡దు',
+'right-apihighlimits' => 'API à°ªà±\8dà°°à°¶à±\8dనలà±\8dà°²à±\8b à°\89à°¨à±\8dనత à°ªà°°à°¿à°®à°¿à°¤à±\81లనà±\81 à°µà°¾à°¡à°¡à°\82',
 'right-writeapi' => 'రైట్ API వినియోగం',
 'right-delete' => 'పేజీలను తొలగించడం',
 'right-bigdelete' => 'చాలా పెద్ద చరితం ఉన్న పేజీలను తొలగించు',
 'right-deleterevision' => 'పేజీల ప్రత్యేకించిన కూర్పులను తొలగించు, తొలగింపును నివారించు',
 'right-deletedhistory' => 'తొలగింపులను, వాటి పాఠ్యం లేకుండా, చరితంలో చూడు',
 'right-deletedtext' => 'తొలగించిన పాఠ్యాన్ని మరియు తొలగించిన కూర్పుల మధ్య మార్పలని చూడగలగడం',
-'right-browsearchive' => 'à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80లనà±\81 à°µà±\86à°¤à±\81à°\95à±\81',
+'right-browsearchive' => 'à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80à°²à±\8dà°²à±\8b à°µà±\86à°¤à°\95à°¡à°\82',
 'right-undelete' => 'పేజీ తొలగింపును రద్దు చెయ్యి',
 'right-suppressrevision' => 'నిర్వాహకులకు కనబడకుండా ఉన్న కూర్పులను సమీక్షించి పునస్థాపించడం',
 'right-suppressionlog' => 'గోప్యంగా ఉన్న లాగ్‌లను చూడడం',
@@ -1452,8 +1459,8 @@ $1",
 'right-editsemiprotected' => '"{{int:protect-level-autoconfirmed}}" గా సంరక్షించబడ్డ పేజీలను మార్చు',
 'right-editinterface' => 'యూజరు ఇంటరుఫేసులో దిద్దుబాటు చెయ్యి',
 'right-editusercssjs' => 'ఇతర వాడుకరుల CSS, JS ఫైళ్ళలో దిద్దుబాటు చెయ్యి',
-'right-editusercss' => 'à°\87తర à°µà°¾à°¡à±\81à°\95à°°à±\81à°² CSS à°«à±\88à°³à±\8dళలà±\8b à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\86à°¯à±\8dయి',
-'right-edituserjs' => 'à°\87తర à°µà°¾à°¡à±\81à°\95à°°à±\81à°² JS à°«à±\88à°³à±\8dళలà±\8b à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\86à°¯à±\8dయి',
+'right-editusercss' => 'à°\87తర à°µà°¾à°¡à±\81à°\95à°°à±\81à°² CSS à°«à±\88à°³à±\8dళలà±\8b à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\86à°¯à±\8dయడà°\82',
+'right-edituserjs' => 'à°\87తర à°µà°¾à°¡à±\81à°\95à°°à±\81à°² JS à°«à±\88à°³à±\8dళలà±\8b à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\86à°¯à±\8dయడà°\82',
 'right-editmyusercss' => 'మీ స్వంత వాడుకరి CSS ఫైళ్ళను సరిదిద్దండి',
 'right-editmyuserjs' => 'మీ స్వంత JavaScript దస్త్రాలను మార్చండి',
 'right-viewmywatchlist' => 'మీ స్వంత వీక్షణజాబితాను చూడండి',
@@ -1461,22 +1468,22 @@ $1",
 'right-viewmyprivateinfo' => 'మీ స్వంత గోపనీయ డేటాను చూడండి (ఉదా: ఈమెయిలు చిరునామా, అసలు పేరు)',
 'right-editmyprivateinfo' => 'మీ స్వంత గోపనీయ డేటాను మార్చుకోండి (ఉదా: ఈమెయిలు చిరునామా, అసలు పేరు)',
 'right-editmyoptions' => 'మీ స్వంత అభిరుచులను మార్చుకోండి',
-'right-rollback' => 'à°\92à°\95ానà±\8aà°\95 à°ªà±\87à°\9cà±\80à°²à±\8b à°\9aివరి à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\87సిన à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\9aà±\87సిన à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dలనà±\81 à°°à°¦à±\8dà°¦à±\81à°\9aà±\87యి',
+'right-rollback' => 'à°\92à°\95ానà±\8aà°\95 à°ªà±\87à°\9cà±\80à°²à±\8b à°\9aివరి à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\87సిన à°µà°¾à°¡à±\81à°\95à°°à°¿ à°\9aà±\87సిన à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dలనà±\81 à°°à°¦à±\8dà°¦à±\81à°\9aà±\87యడà°\82',
 'right-markbotedits' => 'వెనక్కి తెచ్చిన దిద్దుబాట్లను బాట్ దిద్దుబాట్లుగా గుర్తించు',
 'right-noratelimit' => 'రేటు పరిమితులు ప్రభావం చూపవు',
-'right-import' => 'ఇతర వికీల నుండి పేజీలను దిగుమతి చేసుకో',
-'right-importupload' => 'à°«à±\88à°²à±\81 à°\85à°ªà±\8dâ\80\8cà°²à±\8bà°¡à±\81 à°¨à±\81à°\82à°¡à°¿ à°ªà±\87à°\9cà±\80లనà±\81 à°¦à°¿à°\97à±\81మతి à°\9aà±\87à°¸à±\81à°\95à±\8b',
+'right-import' => 'ఇతర వికీల నుండి పేజీలను దిగుమతి చేసుకోవడం',
+'right-importupload' => 'à°«à±\88à°²à±\81 à°\8eà°\95à±\8dà°\95à°¿à°\82à°ªà±\81 à°¨à±\81à°\82à°¡à°¿ à°ªà±\87à°\9cà±\80లనà±\81 à°¦à°¿à°\97à±\81మతి à°\9aà±\87à°¸à±\81à°\95à±\8bవడà°\82',
 'right-patrol' => 'ఇతరుల దిద్దుబాట్లను నిఘాలో ఉన్నట్లుగా గుర్తించు',
 'right-autopatrol' => 'తానే చేసిన మార్పులను నిఘాలో ఉన్నట్లుగా ఆటోమాటిగా గుర్తించు',
 'right-patrolmarks' => 'ఇటీవలి మార్పుల నిఘా గుర్తింపులను చూడు',
 'right-unwatchedpages' => 'వీక్షణలో లేని పేజీల జాబితాను చూడు',
-'right-mergehistory' => 'à°ªà±\87à°\9cà±\80à°² à°¯à±\8aà°\95à±\8dà°\95 à°\9aà°°à°¿à°¤à±\8dరలని à°µà°¿à°²à±\80à°¨à°\82 à°\9aà±\87à°¯à°\97à°²à°\97à°¡à°\82',
+'right-mergehistory' => 'పేజీల యొక్క చరిత్రలని విలీనం చేయడం',
 'right-userrights' => 'వాడుకరులందరి హక్కులను మార్చు',
 'right-userrights-interwiki' => 'ఇతర వికీల్లోని వాడుకరుల హక్కులను మార్చు',
 'right-siteadmin' => 'డేటాబేసును లాక్, అన్‌లాక్ చెయ్యి',
 'right-override-export-depth' => '5 లింకుల లోతు వరకు ఉన్న పేజీలతో సహా, పేజీలను ఎగుమతి చెయ్యి',
-'right-sendemail' => 'à°\87తర à°µà°¾à°¡à±\81à°\95à°°à±\81à°²à°\95à±\81 à°\88-à°®à±\86యిలà±\81 à°ªà°\82పిà°\82à°\9aà°\97à°²à°\97à°¡à°\82',
-'right-passwordreset' => 'à°¸à°\82à°\95à±\87తపదానà±\8dని à°ªà±\81నరà±\81à°¦à±\8dధరిà°\82à°\9aà°¿à°¨ à°\88-à°®à±\86యిళà±\8dà°³à±\81',
+'right-sendemail' => 'ఇతర వాడుకరులకు ఈ-మెయిలు పంపించడం',
+'right-passwordreset' => 'à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°ªà±\81 à°\88à°®à±\86యిళà±\8dళనà±\81 à°\9aà±\82à°¡à°¡à°\82',
 
 # Special:Log/newusers
 'newuserlogpage' => 'కొత్త వాడుకరుల చిట్టా',
@@ -1487,15 +1494,15 @@ $1",
 'rightslogtext' => 'ఇది వాడుకరుల హక్కులకు జరిగిన మార్పుల చిట్టా.',
 
 # Associated actions - in the sentence "You do not have permission to X"
-'action-read' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°\9aదవà°\82à°¡à°¿',
+'action-read' => 'à°\88 à°ªà±\87à°\9cà±\80ని à°\9aదివà±\87',
 'action-edit' => 'ఈ పేజీని సవరించే',
 'action-createpage' => 'పేజీలను సృష్టించే',
 'action-createtalk' => 'చర్చాపేజీలను సృష్టించే',
 'action-createaccount' => 'ఈ వాడుకరి ఖాతాని సృష్టించే',
-'action-minoredit' => 'à°\88 à°®à°¾à°°à±\8dà°ªà±\81ని à°\9aà°¿à°¨à±\8dనదానిà°\97à°¾ à°\97à±\81à°°à±\8dతిà°\82à°\9aà±\87',
+'action-minoredit' => 'ఈ మార్పుని చిన్నదిగా గుర్తించే',
 'action-move' => 'ఈ పేజీని తరలించే',
-'action-move-subpages' => 'ఈ పేజీని మరియు దీని ఉపపేజీలను తరలించే',
-'action-move-rootuserpages' => 'à°ªà±\8dరధాన à°µà°¾à°¡à±\81à°\95à°°à°¿ à°ªà±\87à°\9cà±\80లని à°¤à°°à°²à°¿à°\82à°\9aà°\97à°¡à°\97à°¡à°\82',
+'action-move-subpages' => 'ఈ పేజీని, దీని ఉపపేజీలనూ తరలించే',
+'action-move-rootuserpages' => 'à°ªà±\8dరధాన à°µà°¾à°¡à±\81à°\95à°°à°¿ à°ªà±\87à°\9cà±\80లని à°¤à°°à°²à°¿à°\82à°\9aà±\87',
 'action-movefile' => 'ఈ ఫైలుని తరలించే',
 'action-upload' => 'ఈ దస్త్రాన్ని ఎక్కించే',
 'action-reupload' => 'ఈ ఫైలుని తిరగవ్రాసే',
@@ -1521,7 +1528,7 @@ $1",
 'action-userrights' => 'అందరు వాడుకరుల హక్కులను మార్చే',
 'action-userrights-interwiki' => 'ఇతర వికీలలో వాడుకరుల యొక్క హక్కులను మార్చే',
 'action-siteadmin' => 'డాటాబేసుకి తాళం వేసే లేదా తీసే',
-'action-sendemail' => 'ఈ-మెయిల్స్ పంపించు',
+'action-sendemail' => 'ఈమెయిళ్ళు పంపించే',
 'action-editmywatchlist' => 'మీ వీక్షణ జాబితాను సరిదిద్దండి',
 'action-viewmywatchlist' => 'మీ వీక్షణ జాబితాను చూడండి',
 'action-viewmyprivateinfo' => 'మీ గోపనీయ సమాచారాన్ని చూడండి',
@@ -1529,7 +1536,7 @@ $1",
 
 # Recent changes
 'nchanges' => '{{PLURAL:$1|ఒక మార్పు|$1 మార్పులు}}',
-'enhancedrc-since-last-visit' => '$1 {{PLURAL:$1|చివరి దర్శనం నుండి}}',
+'enhancedrc-since-last-visit' => '{{PLURAL:$1|చివరి సందర్శన తరువాత}}, $1',
 'enhancedrc-history' => 'చరితం',
 'recentchanges' => 'ఇటీవలి మార్పులు',
 'recentchanges-legend' => 'ఇటీవలి మార్పుల ఎంపికలు',
@@ -1543,8 +1550,8 @@ $1",
 'recentchanges-label-plusminus' => 'ఈ పేజి పరిమాణంలో  జరిగిన మార్పుల  బైట్ల సంఖ్య',
 'recentchanges-legend-heading' => "'''సూచిక :'''",
 'recentchanges-legend-newpage' => '([[Special:NewPages|కొత్త పేజీల జాబితా]]ను కూడా చూడండి)',
-'rcnotefrom' => '<b>$2</b> నుండి జరిగిన మార్పులు (<b>$1</b> వరకు చూపబడ్డాయి).',
-'rclistfrom' => '$1 నుండి జరిగిన మార్పులను చూపించు',
+'rcnotefrom' => '<strong>$2</strong> నుండి జరిగిన మార్పులు (<strong>$1</strong> వరకు) కింద చూపబడ్డాయి.',
+'rclistfrom' => '$3, $2 నుండి జరిగిన మార్పులను చూపించు',
 'rcshowhideminor' => 'చిన్న మార్పులను $1',
 'rcshowhideminor-show' => 'చూపించు',
 'rcshowhideminor-hide' => 'దాచు',
@@ -1584,10 +1591,10 @@ $1",
 'recentchangeslinked' => 'సంబంధిత మార్పులు',
 'recentchangeslinked-feed' => 'సంబంధిత మార్పులు',
 'recentchangeslinked-toolbox' => 'సంబంధిత మార్పులు',
-'recentchangeslinked-title' => '$1 కు సంబంధించిన మార్పులు',
+'recentchangeslinked-title' => '"$1" కు సంబంధించిన మార్పులు',
 'recentchangeslinked-summary' => 'ఏదైనా పేజీకి లింకై ఉన్న పేజీల్లో (లేదా ఏదైనా వర్గంలోని పేజీల్లో) జరిగిన ఇటీవలి మార్పుల జాబితా ఇది.  [[Special:Watchlist|మీ వీక్షణ జాబితా]]లో ఉన్న పేజీలు <strong>బొద్దు</strong>గా ఉంటాయి.',
 'recentchangeslinked-page' => 'పేజీ పేరు:',
-'recentchangeslinked-to' => 'ఇచ్చిన పేజీకి లింకయివున్న పేజీలలో జరిగిన మార్పులను చూపించు',
+'recentchangeslinked-to' => 'à°²à±\87à°¦à°\82à°\9fà±\87, à°\87à°\9aà±\8dà°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80à°\95à°¿ à°²à°¿à°\82à°\95యివà±\81à°¨à±\8dà°¨ à°ªà±\87à°\9cà±\80లలà±\8b à°\9cà°°à°¿à°\97à°¿à°¨ à°®à°¾à°°à±\8dà°ªà±\81లనà±\81 à°\9aà±\82పిà°\82à°\9aà±\81',
 
 # Upload
 'upload' => 'దస్త్రపు ఎక్కింపు',
@@ -1596,8 +1603,8 @@ $1",
 'upload-tryagain' => 'మార్చిన ఫైలు వివరణని దాఖలుచేయండి',
 'uploadnologin' => 'లాగిన్‌ అయిలేరు',
 'uploadnologintext' => 'దస్త్రాలను ఎక్కించడానికి మీరు $1 ఉండాలి.',
-'upload_directory_missing' => 'à°\8eà°\97à±\81మతి à°¡à±\88à°°à±\86à°\95à±\8dà°\9fà°°à±\80 ($1) à°¤à°ªà±\8dపిà°\82ది à°®à°°à°¿à°¯à±\81 à°µà±\86à°¬à±\8d à°¸à°°à±\8dవరà±\8d à°¦à°¾à°¨à±\8dని à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà°²à±\87à°\95à±\81à°¨à±\8dà°¨ది.',
-'upload_directory_read_only' => 'à°\85à°ªà±\8dâ\80\8cà°²à±\8bà°¡ు డైరెక్టరీ ($1), వెబ్‌సర్వరు రాసేందుకు అనుకూలంగా లేదు.',
+'upload_directory_missing' => 'à°\8eà°\95à±\8dà°\95à°¿à°\82à°ªà±\81 à°¡à±\88à°°à±\86à°\95à±\8dà°\9fà°°à±\80 ($1) à°\95నబడలà±\87à°¦à±\81. à°ªà±\88à°\97à°¾ à°µà±\86à°¬à±\8d à°¸à°°à±\8dవరà±\8d à°¦à°¾à°¨à±\8dని à°¸à±\83à°·à±\8dà°\9fà°¿à°\82à°\9aà°²à±\87à°\95à°ªà±\8bయిà°\82ది.',
+'upload_directory_read_only' => 'à°\8eà°\95à±\8dà°\95à°¿à°\82à°ªు డైరెక్టరీ ($1), వెబ్‌సర్వరు రాసేందుకు అనుకూలంగా లేదు.',
 'uploaderror' => 'ఎక్కింపు లోపం',
 'upload-recreate-warning' => "'''హెచ్చరిక: ఆ పేరుతో ఉన్న దస్త్రాన్ని తరలించి లేదా తొలగించి ఉన్నారు.'''
 
@@ -1614,29 +1621,30 @@ $1",
 'upload-prohibited' => 'నిషేధించిన ఫైలు రకాలు: $1.',
 'uploadlog' => 'ఎక్కింపుల చిట్టా',
 'uploadlogpage' => 'ఎక్కింపుల చిట్టా',
-'uploadlogpagetext' => 'ఇటీవల జరిగిన ఫైలు అప్‌లోడుల జాబితా ఇది.',
+'uploadlogpagetext' => 'ఇటీవల జరిగిన ఫైలు అప్‌లోడుల జాబితా ఇది.
+మరింత దృశ్యాత్మకంగా చూడటం కోసం [[Special:NewFiles|కొత్త ఫైళ్ళ కొలువు]]కు వెళ్ళండి.',
 'filename' => 'ఫైలు పేరు',
 'filedesc' => 'సారాంశం',
 'fileuploadsummary' => 'సారాంశం:',
 'filereuploadsummary' => 'ఫైలు మార్పులు:',
 'filestatus' => 'కాపీహక్కు స్థితి:',
 'filesource' => 'మూలం:',
-'uploadedfiles' => 'à°\8eà°\97à±\81మతయిన ఫైళ్ళు',
+'uploadedfiles' => 'à°\8eà°\95à±\8dà°\95à°¿à°\82à°\9aిన ఫైళ్ళు',
 'ignorewarning' => 'హెచ్చరికను పట్టించుకోకుండా ఫైలును భద్రపరచు',
 'ignorewarnings' => 'హెచ్చరికలను పట్టించుకోవద్దు',
-'minlength1' => 'పైలు పేర్ల కనీసం ఒక్క అక్షరమైనా ఉండాలి.',
+'minlength1' => 'పైలు పేర్ల నిడివి కనీసం ఒక్క అక్షరమైనా ఉండాలి.',
 'illegalfilename' => '"$1" అనే దస్త్రపుపేరు పేజీ శీర్షికలలో వాడకూడని అక్షరాలను కలిగివుంది.
 దస్త్రపు పేరుని మార్చి మళ్ళీ ఎక్కించడానికి ప్రయత్నించండి.',
 'filename-toolong' => 'దస్త్రపు పేరు 240 బైట్ల కంటే పొడవు ఉండకూడదు.',
 'badfilename' => 'ఫైలు పేరు "$1"కి మార్చబడినది.',
-'filetype-mime-mismatch' => 'దసà±\8dà°¤à±\8dà°°à°ªà±\81 à°ªà±\8aà°¡à°\97à°¿à°\82à°ªà±\81 ".$1" ఆ దస్త్రం యొక్క MIME రకం ($2) తో సరిపోలలేదు.',
+'filetype-mime-mismatch' => 'దసà±\8dà°¤à±\8dà°°à°ªà±\81 à°\8eà°\95à±\8dà°¸à±\8dà°\9fà±\86à°¨à±\8dà°·à°¨à±\81 ".$1", ఆ దస్త్రం యొక్క MIME రకం ($2) తో సరిపోలలేదు.',
 'filetype-badmime' => '"$1" MIME రకం ఉన్న ఫైళ్ళను ఎగుమతికి అనుమతించం.',
-'filetype-bad-ie-mime' => 'ఈ ఫైలుని ఎగుమతి చేయలేరు ఎందుకంటే ఇంటర్నెట్ ఎక్స్‌ప్లోరర్ దీన్ని "$1" గా చూపిస్తుంది, ఇది అనుమతి లేని మరియు ప్రమాదకారమైన ఫైలు రకం.',
-'filetype-unwanted-type' => "'''\".\$1\"''' అనేది అవాంఛిత ఫైలు రకం.
-\$2 {{PLURAL:\$3|అనేది వాడదగ్గ ఫైలు రకం|అనేవి వాడదగ్గ ఫైలు రకాలు}}.",
+'filetype-bad-ie-mime' => 'ఈ ఫైలుని ఎగుమతి చేయలేరు. ఎందుకంటే ఇంటర్నెట్ ఎక్స్‌ప్లోరర్ దీన్ని "$1" గా చూపిస్తుంది. ఇది అనుమతి లేని మరియు ప్రమాదకరమైన ఫైలు రకం.',
+'filetype-unwanted-type' => '<strong>".$1"</strong> అనేది అవాంఛిత ఫైలు రకం.
+$2 {{PLURAL:$3|అనేది వాడదగ్గ ఫైలు రకం|అనేవి వాడదగ్గ ఫైలు రకాలు}}.',
 'filetype-banned-type' => '\'\'\'".$1"\'\'\' {{PLURAL:$4|అనేది అనుమతించబడిన ఫైలు రకం కాదు|అనేవి అనుమతించబడిన ఫైలు రకాలు కాదు}}.
 అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}} $2.',
-'filetype-missing' => 'à°«à±\88à°²à±\81à°\95à°¿ à°ªà±\8aà°¡à°\97à°¿à°\82à°ªు (".jpg" లాంటిది) లేదు.',
+'filetype-missing' => 'à°«à±\88à°²à±\81à°\95à°¿ à°\8eà°\95à±\8dà°¸à±\8dà°\9fà±\86à°¨à±\8dà°·à°¨ు (".jpg" లాంటిది) లేదు.',
 'empty-file' => 'మీరు సమర్పించిన దస్త్రం ఖాళీగా ఉంది.',
 'file-too-large' => 'మీరు సమర్పించిన దస్త్రం చాలా పెద్దగా ఉంది.',
 'filename-tooshort' => 'దస్త్రపు పేరు మరీ చిన్నగా ఉంది.',
@@ -1644,23 +1652,24 @@ $1",
 'verification-error' => 'దస్త్రపు తనిఖీలో ఈ దస్త్రం ఉత్తీర్ణమవలేదు.',
 'hookaborted' => 'మీరు చేయప్రత్నించిన మార్పుని ఒక పొడగింత కొక్కెం విచ్ఛిన్నం చేసింది.',
 'illegal-filename' => 'ఆ దస్త్రపుపేరు అనుమతించబడదు.',
-'overwrite' => 'à°\87à°ªà±\8dà°ªà°\9fà°¿à°\95à±\87 à°\89à°¨à±\8dà°¨ à°¦à°¸à±\8dà°¤à±\8dరానà±\8dని à°¤à°¿à°°à°¿à°\97రాయడà°\82 à°\85à°¨à±\81మతిà°\82à°\9aబడదు.',
-'unknown-error' => 'à°\8fà°¦à±\8b à°¤à±\86లియని à°ªà±\8aరపాà°\9fà±\81 à°\9cà°°à°¿à°\97ింది.',
+'overwrite' => 'à°\87à°ªà±\8dà°ªà°\9fà°¿à°\95à±\87 à°\89à°¨à±\8dà°¨ à°¦à°¸à±\8dà°¤à±\8dరానà±\8dని à°¤à°¿à°°à°\97రాయడానిà°\95à°¿ à°\85à°¨à±\81మతి à°²à±\87దు.',
+'unknown-error' => 'à°\8fà°¦à±\8b à°¤à±\86లియని à°²à±\8bà°ªà°\82 à°¦à±\8aà°°à±\8dà°²ింది.',
 'tmp-create-error' => 'తాత్కాలిక దస్త్రాన్ని సృష్టించలేకపోయాం.',
 'tmp-write-error' => 'తాత్కాలిక దస్త్రాన్ని రాయడంలో పొరపాటు.',
 'large-file' => 'ఫైళ్ళు $1 కంటే పెద్దవిగా ఉండకుండా ఉంటే మంచిది; ఈ ఫైలు $2 ఉంది.',
 'largefileserver' => 'ఈ ఫైలు సైజు సర్వరులో విధించిన పరిమితి కంటే ఎక్కువగా ఉంది.',
 'emptyfile' => 'మీరు అప్‌లోడు చేసిన ఫైలు ఖాళీగా ఉన్నట్లుంది. ఫైలు పేరును ఇవ్వడంలో స్పెల్లింగు తప్పు దొర్లి ఉండొచ్చు. మీరు అప్‌లోడు చెయ్యదలచింది ఇదో కాదో నిర్ధారించుకోండి.',
-'windows-nonascii-filename' => 'దస్త్రాల పేర్లలో ప్రత్యేక అక్షరాలకు ఈ వికీలో తోడ్పాటు లేదు.',
-'fileexists' => 'ఈ పేరుతో ఒక ఫైలు ఇప్పటికే ఉంది.
-దీనిని మీరు మార్చాలో లేదో తెలియకపోతె ఫైలు <strong>[[:$1]]</strong>ని చూడండి.
+'windows-nonascii-filename' => 'దస్త్రాల పేర్లలో ప్రత్యేక అక్షరాలకు ఈ వికీలో అనుకూలత లేదు.',
+'fileexists' => 'ఈ పేరుతో ఒక ఫైలు ఇప్పటికే ఉంది. దీనిని మార్చాలో లేదో తెలియకపోతే ఫైలు <strong>[[:$1]]</strong>ను చూడండి.
 [[$1|thumb]]',
-'filepageexists' => 'ఈ ఫైలు కొరకు వివరణ పేజీని <strong>[[:$1]]</strong> వద్ద ఈసరికే సృష్టించారు, కానీ ఆ పేరుతో ప్రస్తుతం ఏ ఫైలూ లేదు. మీరు ఇస్తున్న సంగ్రహం ఆ వివరణ పేజీలో కనబడదు. మీ సంగ్రహం అక్కడ కనబడాలంటే, నేరుగా అక్కడే చేర్చాలి.
+'filepageexists' => 'ఈ ఫైలు కొరకు వివరణ పేజీని <strong>[[:$1]]</strong> వద్ద ఈసరికే సృష్టించారు, కానీ ఆ పేరుతో ప్రస్తుతం ఫైలేదీ లేదు.
+మీరు ఇస్తున్న సంగ్రహం ఆ వివరణ పేజీలో కనబడదు. 
+మీ సంగ్రహం అక్కడ కనబడాలంటే, నేరుగా అక్కడే చేర్చాలి.
 [[$1|thumb]]',
-'fileexists-extension' => 'ఇటువంటి పేరుతో మరో ఫైలు ఉంది: [[$2|thumb]]
-* à°\8eà°\97à±\81మతి à°\9aà±\87స్తున్న ఫైలు పేరు: <strong>[[:$1]]</strong>
+'fileexists-extension' => 'ఇటువంటి పేరుతోటే మరో ఫైలు ఉంది: [[$2|thumb]]
+* à°\8eà°\95à±\8dà°\95à°¿స్తున్న ఫైలు పేరు: <strong>[[:$1]]</strong>
 * ప్రస్తుతం ఉన్న ఫైలు పేరు: <strong>[[:$2]]</strong>
-దయà°\9aà±\87సి à°®à°°à±\8b à°ªà±\87à°°à±\81 à°\8eà°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿.',
+మరో పేరు ఎంచుకోండి.',
 'fileexists-thumbnail-yes' => "ఈ ఫైలు కుదించిన బొమ్మ లాగా ఉంది ''(థంబ్‌నెయిలు)''. [[$1|thumb]]
 <strong>[[:$1]]</strong> ఫైలు చూడండి.
 గుర్తు పెట్టబడిన ఫైలు అసలు సైజే అది అయితే, మరో థంబ్‌నెయిలును అప్‌లోడు చెయ్యాల్సిన అవసరం లేదు.",
@@ -3045,6 +3054,7 @@ $1',
 'file-info-size-pages' => '$1 × $2 పిక్సెళ్ళు, దస్త్రపు పరిమాణం: $3, MIME రకం: $4, $5 {{PLURAL:$5|పేజీ|పేజీలు}}',
 'file-nohires' => 'మరింత స్పష్టమైన బొమ్మ లేదు.',
 'svg-long-desc' => 'SVG ఫైలు, నామమాత్రంగా $1 × $2 పిక్సెళ్ళు, ఫైలు పరిమాణం: $3',
+'svg-long-error' => 'చెల్లని SVG దస్త్రం: $1',
 'show-big-image' => 'అసలు దస్త్రం',
 'show-big-image-preview' => 'ఈ మునుజూపు పరిమాణం: $1.',
 'show-big-image-other' => 'ఇతర {{PLURAL:$2|వైశాల్యం|వైశాల్యాలు}}: $1.',
@@ -3690,11 +3700,13 @@ $5
 'version-entrypoints-header-url' => 'చిరునామా',
 
 # Special:Redirect
+'redirect' => 'ఫైలు, వాడుకరి, పేజీ లేదా కూర్పు ఐడీ ప్రకారం దారిమార్పు',
+'redirect-legend' => 'ఫైలు లేదా పేజీకి దారిమార్పు',
 'redirect-submit' => 'వెళ్ళు',
 'redirect-lookup' => 'చూడు:',
 'redirect-value' => 'విలువ:',
 'redirect-user' => 'వాడుకరి ID',
-'redirect-page' => 'à°ªà±\81à°\9f ఐడీ',
+'redirect-page' => 'à°ªà±\87à°\9cà±\80 ఐడీ',
 'redirect-revision' => 'పేజీ కూర్పు',
 'redirect-file' => 'దస్త్రపు పేరు',
 'redirect-not-exists' => 'విలువ కనబడలేదు',
index a910e8e..1397e75 100644 (file)
@@ -725,6 +725,9 @@ $1',
 'suspicious-userlogout' => 'คำขอล็อกเอาต์ของคุณถูกปฏิเสธเพราะดูเหมือนส่งมาจากเบราว์เซอร์หรือพร็อกซีแคชที่เสีย',
 'createacct-another-realname-tip' => 'ไม่จำเป็นต้องใส่ชื่อจริง
 หากคุณเลือกใส่ชื่อจริง จะใช้เพื่อแสดงที่มาสำหรับงานของตน',
+'pt-login' => 'ล็อกอิน',
+'pt-createaccount' => 'สร้างบัญชี',
+'pt-userlogout' => 'ล็อกเอาต์',
 
 # Email sending
 'php-mail-error-unknown' => 'เกิดข้อผิดพลาดไม่ทราบสาเหตุในฟังก์ชัน mail() ของพีเอชพี',
@@ -733,7 +736,7 @@ $1',
 
 # Change password dialog
 'changepassword' => 'เปลี่ยนรหัสผ่าน',
-'resetpass_announce' => 'à¸\84ุà¸\93à¹\83à¸\8aà¹\89รหัสอีà¹\80มลà¸\8aัà¹\88วà¸\84ราวลà¹\87อà¸\81อิà¸\99 à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ำหà¸\99à¸\94รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\95รà¸\87à¸\99ีà¹\89 à¸\88ึà¸\87à¸\88ะà¹\80สรà¹\87à¸\88สิà¹\89à¸\99à¸\82ัà¹\89à¸\99à¸\95อà¸\99à¸\81ารลà¹\87อà¸\81อิà¸\99:',
+'resetpass_announce' => 'à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\95ัà¹\89à¸\87รหัสà¸\9cà¹\88าà¸\99à¹\83หมà¹\88à¸\88ึà¸\87à¸\88ะà¹\80สรà¹\87à¸\88สิà¹\89à¸\99à¸\81ารลà¹\87อà¸\81อิà¸\99',
 'resetpass_text' => '<!-- เพิ่มข้อความที่นี่ -->',
 'resetpass_header' => 'เปลี่ยนรหัสผ่าน',
 'oldpassword' => 'รหัสผ่านเดิม:',
@@ -749,8 +752,13 @@ $1',
 'resetpass-submit-cancel' => 'ยกเลิก',
 'resetpass-wrong-oldpass' => 'รหัสผ่านชั่วคราวหรือปัจจุบันไม่ถูกต้อง
 คุณอาจเปลี่ยนรหัสผ่านของคุณไปแล้ว หรือขอรหัสผ่านชั่วคราวใหม่แล้ว',
+'resetpass-recycled' => 'โปรดตั้งรหัสผ่านใหม่ให้ต่างจากรหัสผ่านปัจจุบัน',
+'resetpass-temp-emailed' => 'คุณล็อกอินด้วยรหัสผ่านชั่วคราวที่ส่งทางอีเมล
+คุณต้องตั้งรหัสผ่านใหม่ที่นี่จึงจะเสร็จสิ้นการล็อกอิน:',
 'resetpass-temp-password' => 'รหัสผ่านชั่วคราว:',
 'resetpass-abort-generic' => 'การเปลี่ยนรหัสผ่านถูกส่วนขยายยกเลิก',
+'resetpass-expired' => 'รหัสผ่านของคุณหมดอายุแล้ว โปรดตั้งรหัสผ่านใหม่เพื่อล็อกอิน',
+'resetpass-expired-soft' => 'รหัสผ่านของคุณหมดอายุแล้วและจำเป็นต้องตั้งใหม่ โปรดเลือกรหัสผ่านใหม่ขณะนี้ หรือคลิก "{{int:resetpass-submit-cancel}}" เพื่อตั้งใหม่ทีหลัง',
 
 # Special:PasswordReset
 'passwordreset' => 'ตั้งรหัสผ่านใหม่',
@@ -1576,14 +1584,26 @@ $1",
 'recentchanges-label-plusminus' => 'ขนาดของหน้าเปลี่ยนไปด้วยจำนวนไบต์เท่านี้',
 'recentchanges-legend-heading' => "'''คำอธิบายสัญลักษณ์:'''",
 'recentchanges-legend-newpage' => '(ดูเพิ่มที่[[Special:NewPages|รายชื่อหน้าใหม่]])',
-'rcnotefrom' => "ด้านล่างเป็นการเปลี่ยนแปลงตั้งแต่ '''$2''' (มากสุด '''$1''' รายการ)",
+'rcnotefrom' => 'ด้านล่างเป็นการเปลี่ยนแปลงตั้งแต่ <strong>$2</strong> (มากสุด <strong>$1</strong> รายการ)',
 'rclistfrom' => 'แสดงการเปลี่ยนแปลงใหม่เริ่มตั้งแต่ $1',
 'rcshowhideminor' => '$1การแก้ไขเล็กน้อย',
+'rcshowhideminor-show' => 'แสดง',
+'rcshowhideminor-hide' => 'ซ่อน',
 'rcshowhidebots' => '$1บอต',
+'rcshowhidebots-show' => 'แสดง',
+'rcshowhidebots-hide' => 'ซ่อน',
 'rcshowhideliu' => '$1ผู้ใช้ลงทะเบียน',
+'rcshowhideliu-show' => 'แสดง',
+'rcshowhideliu-hide' => 'ซ่อน',
 'rcshowhideanons' => '$1ผู้ใช้นิรนาม',
+'rcshowhideanons-show' => 'แสดง',
+'rcshowhideanons-hide' => 'ซ่อน',
 'rcshowhidepatr' => '$1การแก้ไขที่ตรวจสอบแล้ว',
+'rcshowhidepatr-show' => 'แสดง',
+'rcshowhidepatr-hide' => 'ซ่อน',
 'rcshowhidemine' => '$1การแก้ไขของฉัน',
+'rcshowhidemine-show' => 'แสดง',
+'rcshowhidemine-hide' => 'ซ่อน',
 'rclinks' => 'แสดงการปรับปรุงล่าสุด $1 รายการ ในช่วง $2 วันที่ผ่านมา<br />$3',
 'diff' => 'ต่าง',
 'hist' => 'ประวัติ',
@@ -1698,6 +1718,7 @@ $1",
 'file-exists-duplicate' => 'ไฟล์นี้ซ้ำกับ{{PLURAL:$1|ไฟล์|ไฟล์}}ต่อไปนี้:',
 'file-deleted-duplicate' => 'ไฟล์ที่เหมือนไฟล์นี้ ([[:$1]]) เคยถูกลบไปก่อนหน้านี้แล้ว
 คุณควรตรวจสอบว่าประวัติการลบของไฟล์ก่อนดำเนินการอัปโหลดใหม่',
+'file-deleted-duplicate-notitle' => 'ไฟล์ที่เหมือนกับไฟล์นี้เคยถูกลบมาก่อน และชื่อดังกล่าวถูกห้ามใช้ คุณควรสอบถามผู้ที่สามารถดูข้อมูลไฟล์ที่ถูกระงับเพื่อทบทวนสถานการณ์ก่อนดำเนินการอัปโหลดไฟล์อีกครั้ง',
 'uploadwarning' => 'คำเตือนการอัปโหลด',
 'uploadwarning-text' => 'กรุณาแก้ไขคำอธิบายไฟล์ด้านล่างนี้ แล้วลองใหม่อีกครั้ง',
 'savefile' => 'บันทึกไฟล์',
@@ -2031,14 +2052,25 @@ $1',
 'deadendpagestext' => 'หน้าต่อไปนี้ไม่เชื่อมโยงไปหน้าอื่นใน {{SITENAME}}',
 'protectedpages' => 'หน้าที่ถูกล็อก',
 'protectedpages-indef' => 'การล็อกแบบไม่มีกำหนดเท่านั้น',
+'protectedpages-summary' => 'หน้านี้แสดงรายการหน้าที่มีอยู่ซึ่งปัจจุบันถูกล็อก สำหรับรายการชื่อเรื่องที่ถูกป้องกันมิให้สร้าง ดู [[{{#special:ProtectedTitles}}]]',
 'protectedpages-cascade' => 'การล็อกแบบสืบทอดเท่านั้น',
 'protectedpages-noredirect' => 'ซ่อนการเปลี่ยนทาง',
 'protectedpagesempty' => 'ขณะนี้ไม่มีหน้าใดถูกล็อกตามพารามิเตอร์เหล่านี้',
+'protectedpages-timestamp' => 'ตราเวลา',
+'protectedpages-page' => 'หน้า',
+'protectedpages-expiry' => 'หมดอายุ',
+'protectedpages-performer' => 'ผู้ใช้ที่ล็อก',
+'protectedpages-params' => 'พารามิเตอร์การล็อก',
+'protectedpages-reason' => 'เหตุผล',
+'protectedpages-unknown-timestamp' => 'ไม่ทราบ',
+'protectedpages-unknown-performer' => 'ไม่ทราบผู้ใช้',
 'protectedtitles' => 'ชื่อเรื่องที่ถูกป้องกัน',
+'protectedtitles-summary' => 'หน้านี้แสดงรายการชื่อที่ปัจจุบันถูกป้องกันมิให้สร้าง สำหรับรายการหน้าที่มีอยู่ที่ถูกล็อก ดู [[{{#special:ProtectedPages}}]]',
 'protectedtitlesempty' => 'ปัจจุบันไม่มีหัวเรื่องที่ได้รับการป้องกันด้วยพารามิเตอร์เหล่านี้',
 'listusers' => 'รายนามผู้ใช้',
 'listusers-editsonly' => 'แสดงเฉพาะผู้ใช้ที่มีการแก้ไข',
 'listusers-creationsort' => 'เรียงลำดับตามวันสร้าง',
+'listusers-desc' => 'เรียงตามลำดับลด',
 'usereditcount' => 'การแก้ไข $1 ครั้ง',
 'usercreated' => '{{GENDER:$3|ถูกสร้าง}}เมื่อ $1 เวลา $2',
 'newpages' => 'หน้าใหม่',
@@ -2482,6 +2514,7 @@ $1',
 'sp-contributions-search' => 'ค้นหาการแก้ไข',
 'sp-contributions-username' => 'เลขที่อยู่ไอพีหรือชื่อผู้ใช้:',
 'sp-contributions-toponly' => 'แสดงเฉพาะการแก้ไขรุ่นล่าสุด',
+'sp-contributions-newonly' => 'แสดงเฉพาะการแก้ไขที่เป็นการสร้างหน้า',
 'sp-contributions-submit' => 'สืบค้น',
 
 # What links here
@@ -2540,6 +2573,7 @@ $1',
 ดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อก',
 'ipb-blockingself' => 'คุณกำลังบล็อกตัวเอง! แน่ใจแล้วหรือว่าต้องการทำอย่างนั้น',
 'ipb-confirmhideuser' => 'คุณกำลังบล็อกผู้ใช้โดยเป็นผู้ใช้ "ซ่อนผู้ใช้" ซึ่งจะระงับชื่อผู้ใช้ในรายการและหน่วยปูมทั้งหมด คุณแน่ใจหรือว่าต้องการดำเนินการเช่นนั้น',
+'ipb-confirmaction' => 'หากคุณแน่ใจว่าคุณต้องการดำเนินการ โปรดเลือกเขตข้อมูล "{{int:ipb-confirm}}"  ที่อยู่ล่างสุด',
 'ipb-edit-dropdown' => 'แก้ไขสาเหตุการบล็อก',
 'ipb-unblock-addr' => 'ปลดบล็อก $1',
 'ipb-unblock' => 'ปลดบล็อกผู้ใช้หรือเลขที่อยู่ไอพี',
index c738797..d626133 100644 (file)
@@ -132,8 +132,8 @@ $messages = array(
 'mar' => 'mar',
 'apr' => 'apr',
 'may' => 'maý',
-'jun' => 'iýun',
-'jul' => 'iýul',
+'jun' => 'iýn',
+'jul' => 'iýl',
 'aug' => 'awg',
 'sep' => 'sen',
 'oct' => 'okt',
@@ -187,8 +187,8 @@ kiçi kategoriýadan {{PLURAL:$1|sany kiçi kategoriýa|$1 sany kiçi kategoriý
 'vector-action-undelete' => 'Öçürmäni yzyna al',
 'vector-action-unprotect' => 'Goragy üýtget',
 'vector-view-create' => 'Döret',
-'vector-view-edit' => 'Redaktirle',
-'vector-view-history' => 'Geçmişi gör',
+'vector-view-edit' => 'Üýtget',
+'vector-view-history' => 'Taryhy gör',
 'vector-view-view' => 'Oka',
 'vector-view-viewsource' => 'Çeşmäni gör',
 'actions' => 'Hereketler',
@@ -199,19 +199,19 @@ kiçi kategoriýadan {{PLURAL:$1|sany kiçi kategoriýa|$1 sany kiçi kategoriý
 'errorpagetitle' => 'Säwlik',
 'returnto' => '$1.',
 'tagline' => '{{SITENAME}} saýtyndan',
-'help' => 'Ýardam',
-'search' => 'Gözle',
+'help' => 'Kömek',
+'search' => 'Gözleg',
 'searchbutton' => 'Gözle',
 'go' => 'Git',
 'searcharticle' => 'Git',
 'history' => 'Sahypanyň geçmişi',
-'history_short' => 'Geçmiş',
+'history_short' => 'Taryh',
 'updatedmarker' => 'soňky gezek görelim bäri täzelenen',
-'printableversion' => 'Print ediş wersiýasy',
+'printableversion' => 'Çap edilýän wersiýa',
 'permalink' => 'Hemişelik çykgyt',
 'print' => 'Print et',
 'view' => 'Görkez',
-'edit' => 'Redaktirle',
+'edit' => 'Üýtget',
 'create' => 'Döret',
 'editthispage' => 'Bu sahypany redaktirle',
 'create-this-page' => 'Bu sahypany döret',
@@ -225,14 +225,14 @@ kiçi kategoriýadan {{PLURAL:$1|sany kiçi kategoriýa|$1 sany kiçi kategoriý
 'unprotectthispage' => 'Sahypanyň goragyny aýyr',
 'newpage' => 'Täze sahypa',
 'talkpage' => 'Sahypany ara alyp maslahatlaş',
-'talkpagelinktext' => 'Çekişme',
+'talkpagelinktext' => 'Pikir alyşma',
 'specialpage' => 'Ýörite Sahypa',
 'personaltools' => 'Şahsy gurallar',
 'postcomment' => 'Täze bölüm',
 'articlepage' => 'Makalany görkez',
 'talk' => 'Çekişme',
-'views' => 'Keşpler',
-'toolbox' => 'Gural sandygy',
+'views' => 'Görnüşler',
+'toolbox' => 'Gurallar',
 'userpage' => 'Ulanyjy sahypasyny görkez',
 'projectpage' => 'Taslama sahypasyny görkez',
 'imagepage' => 'Faýl sahypasyny görkez',
@@ -244,11 +244,11 @@ kiçi kategoriýadan {{PLURAL:$1|sany kiçi kategoriýa|$1 sany kiçi kategoriý
 'otherlanguages' => 'Başga dillerde',
 'redirectedfrom' => '($1 sahypasyndan gönükdirildi)',
 'redirectpagesub' => 'Gönükdirme sahypasy',
-'lastmodifiedat' => 'Bu sahypa iň soňky gezek $2, $1 senesinde üýtgedildi.',
+'lastmodifiedat' => 'Bu sahypanyň iň soňky üýtgedilen gezegi: $2, $1.',
 'viewcount' => 'Bu sahypa {{PLURAL:$1|bir|$1 }} gezek görülipdir.',
 'protectedpage' => 'Goragly sahypa',
-'jumpto' => 'Git we:',
-'jumptonavigation' => 'ulan',
+'jumpto' => 'Şuňa git:',
+'jumptonavigation' => 'nawigasiýa',
 'jumptosearch' => 'gözle',
 'view-pool-error' => 'Gynansak-da, şu wagt serwerler hetdenaşa işli.
 Biçak köp ulanyjy şu sahypany görmäge synanyşýar.
@@ -266,17 +266,17 @@ $1',
 'copyrightpage' => '{{ns:project}}:Awtorlyk hukugy',
 'currentevents' => 'Oba güzeri',
 'currentevents-url' => 'Project:Oba güzeri',
-'disclaimers' => 'Jogapkärçilikden boýun gaçyrma',
-'disclaimerpage' => 'Project:Umumy jogapkärçilikden boýun gaçyrma',
+'disclaimers' => 'Jogapkärçilikden boýun gaçyrmak',
+'disclaimerpage' => 'Project:Umumy jogapkärçilikden boýun gaçyrmak',
 'edithelp' => 'Nähili redaktirlenýär?',
-'helppage' => 'Help:Içindäkiler',
+'helppage' => 'Help:Mazmuny',
 'mainpage' => 'Baş Sahypa',
-'mainpage-description' => 'Baş Sahypa',
+'mainpage-description' => 'Baş sahypa',
 'policy-url' => 'Project:Ýörelge',
 'portal' => 'Çaýhana',
 'portal-url' => 'Project:Çaýhana',
-'privacy' => 'Gizlinlik ýörelgesi',
-'privacypage' => 'Project:Gizlinlik ýörelgesi',
+'privacy' => 'Gizlinlik syýasaty',
+'privacypage' => 'Project:Gizlinlik syýasaty',
 
 'badaccess' => 'Rugsat säwligi',
 'badaccess-group0' => 'Talap edýän bu işiňizi ýerine ýetirmäge size ygtyýar berilmeýär.',
@@ -288,15 +288,15 @@ See [[Special:Version|version page]].
 Bu sahypany ulanmak üçin MediaWikiniň $1 wersiýasy talap edilýär. [[Special:Version|Wersiýa sahypasyna]] serediň.',
 
 'ok' => 'OK',
-'retrievedfrom' => '"$1" adresinden alyndy.',
+'retrievedfrom' => 'Çeşmesi: "$1"',
 'youhavenewmessages' => 'Size $1 bar. ($2)',
 'youhavenewmessagesmulti' => 'Size $1-de täze habar bar.',
-'editsection' => 'redaktirle',
-'editold' => 'redaktirle',
+'editsection' => 'üýtget',
+'editold' => 'üýtget',
 'viewsourceold' => 'çeşmäni gör',
-'editlink' => 'redaktirle',
-'viewsourcelink' => 'çeşmesini gör',
-'editsectionhint' => '$1 bölümini redaktirle',
+'editlink' => 'üýtget',
+'viewsourcelink' => 'çeşmäni gör',
+'editsectionhint' => 'Bölümi üýtget: $1',
 'toc' => 'Mazmuny',
 'showtoc' => 'görkez',
 'hidetoc' => 'gizle',
@@ -309,10 +309,10 @@ Bu sahypany ulanmak üçin MediaWikiniň $1 wersiýasy talap edilýär. [[Specia
 'feed-invalid' => 'Nädogry ýazylyşyk kanaly görnüşi.',
 'feed-unavailable' => 'Sindikasiýa lentalary elýeterli däl',
 'site-rss-feed' => '$1 RSS lentasy',
-'site-atom-feed' => '$1 Atom lentasy',
+'site-atom-feed' => '$1 — Atom-lenta',
 'page-rss-feed' => '"$1" RSS lentasy',
 'page-atom-feed' => '"$1" Atom lentasy',
-'red-link-title' => '$1 (bu sahypa heniz ýazylmandyr)',
+'red-link-title' => '$1 (heniz ýazylmandyr)',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
 'nstab-main' => 'Sahypa',
@@ -322,7 +322,7 @@ Bu sahypany ulanmak üçin MediaWikiniň $1 wersiýasy talap edilýär. [[Specia
 'nstab-project' => 'Taslama sahypasy',
 'nstab-image' => 'Faýl',
 'nstab-mediawiki' => 'Habarlaşyk',
-'nstab-template' => 'Å\9fablon',
+'nstab-template' => 'Å\9eablon',
 'nstab-help' => 'Ýardam sahypasy',
 'nstab-category' => 'Kategoriýa',
 
@@ -347,9 +347,9 @@ Bar bolan ähli ýörite sahypalary [[Special:SpecialPages|ýörite sahypalar]]
 Maglumat bazasyny gulplan administratoryň düşündirişi: $1',
 'missing-article' => 'Maglumat bazasy tapylmagy talap edilýän "$1" $2 atly sahypa degişli teksti tapyp bilmedi.
 
-Bu Ã½agdaý sahypanyÅ\88 Ã¶Ã§Ã¼rilen bir sahypanyň ozalky wersiýasy bolmaklygyndan ýüze çykýan bolup biler.
+Bu Ã½agdaý sahypanyÅ\88 Ã½oklanylan bir sahypanyň ozalky wersiýasy bolmaklygyndan ýüze çykýan bolup biler.
 
-Eger sebäp ol däl bolsa, programma serişdesinde bir säwlige duşan bolmagyňyz ahmal.
+Eger sebäp ol däl bolsa, programma serişdesinde bir ýalňyşlyga duşan bolmagyňyz ahmal.
 Muny bir [[Special:ListUsers/sysop|administratora]] URL-ni belläp alyp ýetirmekligiňizi haýyş edýäris.',
 'missingarticle-rev' => '(wersiýa#: $1)',
 'missingarticle-diff' => '(Tapawut: $1, $2)',
@@ -408,7 +408,7 @@ Web brauzeriňiziň keşini arassalaýançaňyz käbir sahypalar sessiýaňyzyň
 'yourdomainname' => 'Siziň domeniňiz:',
 'externaldberror' => 'Ýa tassyklama maglumat bazasynyň säwligi bar ýa-da öz ulanyjy hasabyňyzy täzelemegiňize rugsat berilmeýär.',
 'login' => 'Hasaba gir',
-'nav-login-createaccount' => 'Hasaba gir / täze hasap aç',
+'nav-login-createaccount' => 'Hasaba gir / Hasap döret',
 'loginprompt' => '{{SITENAME}} saýtynda sessiýa açmak üçin kukileri işletmegiňiz zerurdyr.',
 'userlogin' => 'Hasaba gir / täze hasap aç',
 'userloginnocreate' => 'Sessiýa aç',
@@ -448,7 +448,7 @@ Ulanyjy atlary baş hem-de setir harplara duýgurdyr.
 'wrongpasswordempty' => 'Paroly boş girizdiňiz. Gaýtadan synanyşmagyňyzy haýyş edýäris.',
 'passwordtooshort' => 'Parollar iň bolmanda {{PLURAL:$1|1 simwoldan|$1 simwoldan}} ybarat bolmalydyr.',
 'password-name-match' => 'Parolyňyz ulanyjy adyňyzdan tapawutly bolmalydyr.',
-'mailmypassword' => 'Maňa e-poçta bilen täze parol iber',
+'mailmypassword' => 'Paroly nol et',
 'passwordremindertitle' => '{{SITENAME}} üçin täze wagtlaýyn parol',
 'passwordremindertext' => 'Kimdir biri (ähtimal özüňiz $1 IP adresinden) {{SITENAME}} ($4) üçin täze parol iberilmegini talap etdi. "$2" ulanyjysy üçin wagtlaýynça "$3" paroly döredildi. Eger bu siziň öz talabyňyz bolsa, onda sessiýa açyp, bir täze parol saýlap almagyňyz zerurdyr. Wagtlaýyn parolyňyzyň möhleti {{PLURAL:$5|1 günden|$5 günden}} gutarjakdyr.
 
@@ -604,10 +604,10 @@ Bu paroly sessiýa açanyňyzdan soňra ''[[Special:ChangePassword|paroly üýtg
 Şonuň üçinem biz ony görkezmek üçin sanlaýyn IP adresini ulanmaly bolýarys.
 Şunuň ýaly IP adresinden ençeme ulanyjy peýdalanýan bolmagy ahmal.
 Eger-de sizem anonim ulanyjy bolsaňyz we size siziň bilen dahyly ýok habarlaşyklar gelýän bolsa, onda mundan beýläk başga anonim ulanyjylar bilen garjaşmazlygyňyz üçin [[Special:UserLogin/signup|özüňize hasap ediniň]] ýa-da [[Special:UserLogin|sessiýa açyň]].''",
-'noarticletext' => 'Bu sahypa häzirki wagtda boş dur.
+'noarticletext' => 'Bu sahypa şu wagt boş dur.
 Bu ady başga sahypalarda [[Special:Search/{{PAGENAME}}|gözläp bilersiňiz]],
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} degişli gündeliklerde gözleg geçirip bilersiňiz],
-ýa-da bu sahypany [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaktirläp bilersiňiz]</span>.',
+ýa-da bu sahypany [{{fullurl:{{FULLPAGENAME}}|action=edit}} üýtgedip bilersiňiz]</span>.',
 'noarticletext-nopermission' => 'Häzirki wagtda bu sahypada tekst ýok.
 Bu sahypa adyny [[Special:Search/{{PAGENAME}}|başga sahypalarda gözläp]]
 ýa-da <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} degişli gündeliklerde gözleg geçirip bilersiňiz]</span>, ýöne bu sahypany döretmäge rugsadyňyz ýok.',
@@ -725,7 +725,7 @@ Ol eýýäm bar.',
 Ol $2 {{PLURAL:$2|çagyryşdan|çagyryşdan}} az bolmalydyr, häzir bu ýerde {{PLURAL:$1|1 sany çagyryş|$1 sany çagyryş}} bar.",
 'expensive-parserfunction-category' => 'Resurs talap ediji funksiýalara çakdanaşa köp çagyryşy bar bolan sahypalar',
 'post-expand-template-inclusion-warning' => "'''Duýduryş''': Girizilen şablonlaryň göwrümi çakdanaşa uly.
-Käbir şablonlar sahypa giriziljek däldir.",
+Käbir şablonlar sahypa girizilmez.",
 'post-expand-template-inclusion-category' => 'Girizilýän şablonlarynyň göwrümi çakdanaşa uly bolan sahypalar',
 'post-expand-template-argument-warning' => "'''Duýduryş:''' Bu sahypa çakdanaşa uly giňeme ölçegi bar bolan iň bolmanda bir sany şablon argumentini öz içine alýar.
 Ol argumentler hasap edilmedi.",
@@ -751,8 +751,8 @@ $3 tarapyndan görkezilen sebäp: ''$2''",
 'viewpagelogs' => 'Bu sahypanyň gündeliklerini görkez',
 'nohistory' => 'Bu sahypanyň özgerdişler geçmişi ýok.',
 'currentrev' => 'Häzirki wersiýa',
-'currentrev-asof' => '$1 senesinden başlap sahypanyň şu wagtky wersiýasy',
-'revisionasof' => 'Sahypanyň $1 senesindäki wersiýasy',
+'currentrev-asof' => '$1 senesinde sahypanyň iň soňky wersiýasy',
+'revisionasof' => '$1 senesindäki wersiýa',
 'revision-info' => '$2 tarapyndan döredilen $1 seneli wersiýa',
 'previousrevision' => '← Ozalkysy',
 'nextrevision' => 'Indikisi →',
@@ -847,7 +847,7 @@ $1",
 'logdelete-success' => "'''Gündelik görünme derejesi şowlulyk bilen sazlandy.'''",
 'logdelete-failure' => "'''Gündelik görünme derejesini sazlap bolmaýar:'''
 $1",
-'revdel-restore' => 'Görnüşi üýtget',
+'revdel-restore' => 'Görnüş ukybyny üýtget',
 'pagehist' => 'Sahypanyň geçmişi',
 'deletedhist' => 'Öçürilen geçmiş',
 'revdelete-hide-current' => '$2, $1 seneli ýazgyda gizleme säwligi: bu häzirki wersiýa.
@@ -902,7 +902,7 @@ Nawigasiýa çykgytlaryny ulanmaklygyň bu sütüni başky ýagdaýyna getirjekd
 # Merge log
 'mergelog' => 'Birleşdirme gündeligi',
 'pagemerge-logentry' => '[[$1]] bilen [[$2]] birleşdirildi (şuňa çenliki wersiýalar: $3)',
-'revertmerge' => 'Böl',
+'revertmerge' => 'Dargat',
 'mergelogpagetext' => 'Aşakdaky sanaw sahypalaryň geçmişleriniň iň soňky birleşdirmelerini görkezýär.',
 
 # Diffs
@@ -916,7 +916,7 @@ Nawigasiýa çykgytlaryny ulanmaklygyň bu sütüni başky ýagdaýyna getirjekd
 
 # Search results
 'searchresults' => 'Gözleg netijeleri',
-'searchresults-title' => '"$1" üçin gözleg netijeleri',
+'searchresults-title' => '"$1" hakda gözleg netijeleri',
 'toomanymatches' => 'Çakdanaşa köp gabat gelme tapyldy, başgaçarak talap ýazyp görüň',
 'titlematches' => 'Sahypa ady gabat gelýär',
 'textmatches' => 'Sahypa teksti gabat gelýär',
@@ -926,19 +926,20 @@ Nawigasiýa çykgytlaryny ulanmaklygyň bu sütüni başky ýagdaýyna getirjekd
 'prevn-title' => 'Öňki $1 {{PLURAL:$1|netije|netije}}',
 'nextn-title' => 'Indiki $1 {{PLURAL:$1|netije|netije}}',
 'shown-title' => 'Sahypa başyna $1 {{PLURAL:$1|netije|netije}} görkez',
-'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3).',
+'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) gör',
 'searchmenu-exists' => "'''Bu wikide \"[[:\$1]]\" atly sahypa bar'''",
-'searchmenu-new' => "'''Bu wikide \"[[:\$1]]\" sahypasyny döret!'''",
-'searchprofile-articles' => 'Mazmunly sahypalar',
-'searchprofile-project' => 'Ýardam we Taslama sahypalary',
+'searchmenu-new' => '<strong>Bu wikide "[[:$1]]" sahypasyny dörediň!</strong> 
+{{PLURAL:$2|0=|Gözlegde tapylan sahypa-da serediň.|Tapylan gözleg netijelerine-de serediň.}}',
+'searchprofile-articles' => 'Esasy sahypalar',
+'searchprofile-project' => 'Kömek we taslama sahypalary',
 'searchprofile-images' => 'Multimedia',
 'searchprofile-everything' => 'Ähli zatlar',
-'searchprofile-advanced' => 'Giňeldilen',
-'searchprofile-articles-tooltip' => '$1 boýunça gözle',
-'searchprofile-project-tooltip' => '$1 boýunça gözle',
+'searchprofile-advanced' => 'Giňişleýin',
+'searchprofile-articles-tooltip' => '$1 içinden gözle',
+'searchprofile-project-tooltip' => '$1 içinden gözle',
 'searchprofile-images-tooltip' => 'Faýllary gözle',
-'searchprofile-everything-tooltip' => 'Ähli sahypalardan gözle (şol sanda çekişme sahypalaryndan)',
-'searchprofile-advanced-tooltip' => 'Hususy at giňişliklerinde gözle',
+'searchprofile-everything-tooltip' => 'Ähli sahypalardan gözle (şol sanda pikir alyşma sahypalaryndan)',
+'searchprofile-advanced-tooltip' => 'Laýyk at giňişliklerinde gözle',
 'search-result-size' => '$1 ({{PLURAL:$2|1 söz|$2 söz}})',
 'search-result-category-size' => '{{PLURAL:$1|1 agza|$1 agza}} ({{PLURAL:$2|1 kiçi kategoriýa|$2 kiçi kategoriýa}}, {{PLURAL:$3|1 faýl|$3 faýl}})',
 'search-result-score' => 'Kybapdaşlyk: $1%',
@@ -954,7 +955,7 @@ Nawigasiýa çykgytlaryny ulanmaklygyň bu sütüni başky ýagdaýyna getirjekd
 'searchall' => 'ählisi',
 'showingresults' => "Aşakda №'''$2''' netijeden başlap, {{PLURAL:$1|'''1''' netije|'''$1''' netije}} görkezilýär.",
 'showingresultsnum' => "Aşakda №'''$2''' netijeden başlap, {{PLURAL:$3|'''1''' netije|'''$3''' netije}} görkezilýär.",
-'showingresultsheader' => "'''$4''' üçin {{PLURAL:$5|'''$3''' netijeden '''$1''' sanysy|'''$3''' netijeden '''$1 - $2''' aralygy}}",
+'showingresultsheader' => "'''$4''' hakda {{PLURAL:$5|'''$3''' netijeden '''$1''' sanysy|'''$3''' netijeden '''$1 - $2''' aralygy}}",
 'search-nonefound' => 'Talaba gabat gelýän hiç hili netije ýok.',
 'powersearch-legend' => 'Giňişleýin gözleg',
 'powersearch-ns' => 'At giňişliklerinde gözleg:',
@@ -1218,7 +1219,7 @@ $1 {{PLURAL:$1|simwoldan|simwoldan}} köp bolmaly däl.',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|üýtgeşme|üýtgeşme}}',
-'recentchanges' => 'Soňky üýtgeşmeler',
+'recentchanges' => 'Soňky üýtgetmeler',
 'recentchanges-legend' => 'Soňky üýtgeşmeleriň opsiýalary',
 'recentchanges-summary' => 'Wikidäki iň soňky üýtgeşmeleri şu sahypadan yzarlaň.',
 'recentchanges-feed-description' => 'Bu lentadaky wikide edilen iň soňky üýtgeşmeleri yzarlaň.',
@@ -1227,19 +1228,19 @@ $1 {{PLURAL:$1|simwoldan|simwoldan}} köp bolmaly däl.',
 'recentchanges-label-bot' => 'Bu özgerdiş bir bot tarapyndan amala aşyryldy',
 'recentchanges-label-unpatrolled' => 'Bu özgerdişe heniz patrullyk edilmändir',
 'recentchanges-legend-newpage' => '$1 - täze sahypa',
-'rcnotefrom' => '<b>$2</b> senesinden bäri edilen özgerdişler aşakda görkezilýär (<b>$1</b> sanysyna çenli).',
+'rcnotefrom' => '<strong>$2</strong> senesinden soňky üýtgetmeler aşakda görkezilýär (<strong>$1</strong> sanysyna çenli).',
 'rclistfrom' => '$1 senesinden bäri edilen özgerdişleri görkez',
 'rcshowhideminor' => 'ujypsyzja özgerdişleri $1',
 'rcshowhidebots' => 'botlary $1',
-'rcshowhideliu' => 'sessiýasy açyk ulanyjylary $1',
+'rcshowhideliu' => 'Hasaba alnan ulanyjylary $1',
 'rcshowhideanons' => 'anonim ulanyjylary $1',
 'rcshowhidepatr' => 'patrullyk edilen özgerdişleri $1',
 'rcshowhidemine' => 'özgerdişlerimi $1',
 'rclinks' => 'Soňky $2 günde edilen iň soňky $1 üýtgeşmäni görkez;<br /> $3',
 'diff' => 'tapawut',
-'hist' => 'geçmiş',
-'hide' => 'gizle',
-'show' => 'görkez',
+'hist' => 'taryh',
+'hide' => 'Gizle',
+'show' => 'Görkez',
 'minoreditletter' => 'uj',
 'newpageletter' => 'T',
 'boteditletter' => 'b',
@@ -1253,10 +1254,10 @@ $1 {{PLURAL:$1|simwoldan|simwoldan}} köp bolmaly däl.',
 # Recent changes linked
 'recentchangeslinked' => 'Degişli üýtgeşmeler',
 'recentchangeslinked-feed' => 'Degişli üýtgeşmeler',
-'recentchangeslinked-toolbox' => 'Degişli üýtgeşmeler',
+'recentchangeslinked-toolbox' => 'Dahylly üýtgetmeler',
 'recentchangeslinked-title' => '"$1" bilen baglanyşykly üýtgeşmeler',
-'recentchangeslinked-summary' => "Aşakdaky sanaw, görkezilen sahypa (ýa-da görkezilen kategoriýanyň agzalaryna) çykgyt berýän sahypalarda edilen üýtgeşmeleriň sanawydyr.
-[[Special:Watchlist|Gözegçilik sanawyňyzdaky]] sahypalar '''goýy''' ýazgy bilen görkezilýär.",
+'recentchangeslinked-summary' => 'Görkezilen sahypa (ýa-da görkezilen kategoriýanyň agzalaryna) çykgyt berýän sahypalarda edilen soňky üýtgetmeleriň sanawy.
+[[Special:Watchlist|Gözegçilik sanawyňyzdaky]] sahypalar <strong>goýy</strong> bilen görkezilýär.',
 'recentchangeslinked-page' => 'Sahypanyň ady:',
 'recentchangeslinked-to' => 'Tersine, berlen sahypa çykgyt berýän sahypalary görkez',
 
@@ -1453,7 +1454,7 @@ Bir sütüniň adyna tyklap sortirowkanyň tertibini üýtgedip bilersiňiz.',
 
 # File description page
 'file-anchor-link' => 'Faýl',
-'filehist' => 'Faýlyň geçmişi',
+'filehist' => 'Faýlyň taryhy',
 'filehist-help' => 'Faýlyň geçmişini görmek üçin Sene/Wagt bölümündäki senelere tyklaň.',
 'filehist-deleteall' => 'ählisini öçür',
 'filehist-deleteone' => 'öçür',
@@ -1466,7 +1467,7 @@ Bir sütüniň adyna tyklap sortirowkanyň tertibini üýtgedip bilersiňiz.',
 'filehist-user' => 'Ulanyjy',
 'filehist-dimensions' => 'Ölçegler',
 'filehist-filesize' => 'Faýl ölçegi',
-'filehist-comment' => 'Teswirleme',
+'filehist-comment' => 'Teswir',
 'filehist-missing' => 'Faýl ýok',
 'imagelinks' => 'Faýlyň ulanylyşy',
 'linkstoimage' => 'Bu faýla çykgydy bar bolan {{PLURAL:$1|sahypa|$1 sahypa}}:',
@@ -1479,8 +1480,8 @@ Aşakdaky sanaw diňe şu faýla çykgyt berýän {{PLURAL:$1|ilkinji faýly |il
 'sharedupload' => 'Bu faýl $1 ammaryndan, özem beýleki taslamalarda ulanylýan bolmagy ahmal.',
 'sharedupload-desc-there' => 'Bu faýl $1 ammaryndan, özem beýleki taslamalarda ulanylýan bolmagy ahmal.
 Goşmaça maglumat üçin [$2 faýl düşündiriş sahypasyna] serediň.',
-'sharedupload-desc-here' => 'Bu faýl $1 ammaryndan, özem beýleki taslamalarda ulanylýan bolmagy ahmal.
-[$2 Onuň faýl düşündiriş sahypasyndaky] düşündirişi aşakda görkezilýär.',
+'sharedupload-desc-here' => 'Bu faýl $1 toplaýjysyndan, özem başga taslamalarda ulanylýan bolmagy mümkin.
+Onuň [$2 faýl düşündiriş sahypasyndaky] maglumatlar aşakda görkezilýär.',
 'filepage-nofile' => 'Şeýle atly faýl ýok.',
 'filepage-nofile-link' => 'Şeýle atly faýl ýok, ama siz [$1 ony ýükläp bilersiňiz].',
 'uploadnewversion-linktext' => 'Bu faýlyň täze wersiýasyny ýükläň',
@@ -1535,7 +1536,7 @@ Giriş formaty: mazmuntip/kiçitip, meselem <code>surat/jpeg</code>.',
 'unusedtemplateswlh' => 'başga çykgytlar',
 
 # Random page
-'randompage' => 'Mesaýy makala',
+'randompage' => 'Çemgeldik sahypa',
 'randompage-nopages' => 'Aşakdaky {{PLURAL:$2|at giňişliginde|at giňişliklerinde}} hiç hili sahypa ýok: $1.',
 
 # Random redirect
@@ -1975,8 +1976,8 @@ Sahypanyň geçmişini saýlap dikeltmek üçin dikeldilmeli wersiýalaryň gutu
 Ulanan çykgydyňyz nädogry bolmagy ýa-da onuň arhiwden dikeldilen ýa-da aýyrylan bolmagy mümkin.',
 'undelete-nodiff' => 'Hiç hili öňki wersiýa tapylmady.',
 'undeletebtn' => 'Dikelt',
-'undeletelink' => 'görkez/dikelt',
-'undeleteviewlink' => 'görkez',
+'undeletelink' => 'gör/dikelt',
+'undeleteviewlink' => 'gör',
 'undeleteinvert' => 'Saýlanmadyklar',
 'undeletecomment' => 'Sebäp:',
 'undeletedrevisions' => '{{PLURAL:$1|1 wersiýa|$1 wersiýa}} dikeldildi',
@@ -2038,7 +2039,7 @@ Salgylanmak üçin iň soňky blokirleme gündeligi ýazgysy aşakda berilýär:
 'sp-contributions-submit' => 'Gözle',
 
 # What links here
-'whatlinkshere' => 'Bu sahypa çykgytlar',
+'whatlinkshere' => 'Şu ýere çykgytlar',
 'whatlinkshere-title' => '"$1" makalasyna çykgyt berýän sahypalar',
 'whatlinkshere-page' => 'Sahypa:',
 'linkshere' => "'''[[:$1]]''' sahypasyna çykgyt berýän sahypalar:",
@@ -2111,8 +2112,8 @@ Aşakda blokirlemäniň takyk sebäbini ýazyň (meselem: wandalizm eden sahypal
 'ipblocklist-empty' => 'Blokirleme sanawy boş.',
 'ipblocklist-no-results' => 'Talap edilen IP adresi ýa-da ulanyjy ady blokirlengi däl.',
 'blocklink' => 'blokirle',
-'unblocklink' => 'blokirowkany aýyr',
-'change-blocklink' => 'blokirowkany üýtget',
+'unblocklink' => 'blokirlemäni aýyr',
+'change-blocklink' => 'blokirlemäni üýtget',
 'contribslink' => 'goşantlar',
 'autoblocker' => 'Awtomatik usulda blokirlendiňiz, çünki ýaňy-ýakynda IP adresiňiz "[[User:$1|$1]]" ulanyjysy tarapyndan ulanyldy. $1 atly ulanyjynyň blokirlenmegi üçin görkezilen sebäp: "\'\'\'$2\'\'\'"',
 'blocklogpage' => 'Blokirleme gündeligi',
@@ -2253,7 +2254,7 @@ Gündeligiň iň soňky ýazgysy salgylanmak üçin aşakda berilýär:",
 Başga bir at saýlaň.',
 
 # Export
-'export' => 'Sahypa eksportirle',
+'export' => 'Sahypalary çykar',
 'exporttext' => 'Belli bir sahypanyň ýa-da sahypalar toplumynyň tekstini we redaktirleme geçmişini XML arkaly eksportirläp bilersiňiz.
 Soňra ony [[Special:Import|importirleme sahypasynyň]] üsti bilen MediaWiki ulanýan başga bir wikä importirläp bolýar.
 
@@ -2353,54 +2354,53 @@ Kompýuteriňize ýazdyryň we şu ýere ýükläň.',
 'tooltip-pt-mytalk' => 'Pikir alyşma sahypaňyz',
 'tooltip-pt-anontalk' => 'Bu IP adresinden edilen özgerdişler barada pikir alyş',
 'tooltip-pt-preferences' => 'Ileri tutmalaryňyz',
-'tooltip-pt-watchlist' => 'Gözegçilikde saklaýan sahypalarym',
+'tooltip-pt-watchlist' => 'Üýtgetmelerini gözegçilikde saklaýan sahypalaryňyz',
 'tooltip-pt-mycontris' => 'Eden goşantlaryňyzyň sanawy',
-'tooltip-pt-login' => 'Hasaba girmegiňiz maslahat berilýär, ýöne hökmany däl.',
+'tooltip-pt-login' => 'Hasaba girmegiňiz maslahat berilýär, ýöne hökman däl.',
 'tooltip-pt-logout' => 'Hasapdan çyk',
-'tooltip-ca-talk' => 'Sahypanyň mazmuny barada garaýşyňy beýan et',
-'tooltip-ca-edit' => 'Bu sahypany redaktirläp bilersiňiz. Ýazdyrmankaňyz synlap görmekligi ýatdan çykarmaň.',
+'tooltip-ca-talk' => 'Esasy sahypa barada çekişme',
+'tooltip-ca-edit' => 'Bu sahypany üýtgedip bilersiňiz. Ýazdyrmankaňyz "synlaw" düwmesine basyp, synlap görüň.',
 'tooltip-ca-addsection' => 'Täze bölüm başlat',
-'tooltip-ca-viewsource' => 'Bu sahypa gorag astynda.
-Onuň çeşmesini görüp bilersiňiz',
-'tooltip-ca-history' => 'Bu sahypanyň ozalky wersiýalary',
+'tooltip-ca-viewsource' => 'Bu sahypa goragly, ýöne onuň çeşmesini görüp bilersiňiz',
+'tooltip-ca-history' => 'Sahypanyň öňki wersiýalary',
 'tooltip-ca-protect' => 'Sahypany goraga al',
 'tooltip-ca-unprotect' => 'Bu sahypanyň goragyny üýtget',
 'tooltip-ca-delete' => 'Sahypany öçür',
 'tooltip-ca-undelete' => 'Bu sahypadaky özgerdişleri öçürilmänkäki ýagdaýyna yzyna dikelt',
 'tooltip-ca-move' => 'Sahypanyň adyny üýtget',
-'tooltip-ca-watch' => 'Bu sahypany gözegçilige al',
+'tooltip-ca-watch' => 'Sahypany gözegçilik sanawyňa goş',
 'tooltip-ca-unwatch' => 'Bu sahypany gözegçilik sanawyňdan aýyr',
-'tooltip-search' => '{{SITENAME}} boýunça gözle',
+'tooltip-search' => '{{SITENAME}} saýtynda gözle',
 'tooltip-search-go' => 'Eger bar bolsa, anyk şu atdaky sahypa git',
-'tooltip-search-fulltext' => 'Şu tekst bar bolan sahypalary gözle',
+'tooltip-search-fulltext' => 'Sahypalardan şu teksti gözle',
 'tooltip-p-logo' => 'Baş sahypa baryp gör',
 'tooltip-n-mainpage' => 'Baş sahypa baryp gör',
 'tooltip-n-mainpage-description' => 'Baş sahypa baryp gör',
 'tooltip-n-portal' => 'Taslama hakynda, nämeler edip bolar, nämeler nirede',
 'tooltip-n-currentevents' => 'Bolup geçýän wakalar barada iň täze maglumatlar',
-'tooltip-n-recentchanges' => 'Wikidäki soňky üýtgeşmeleriň sanawy',
-'tooltip-n-randompage' => 'Çem gelen sahypa git',
-'tooltip-n-help' => 'Kömek almak üçin',
-'tooltip-t-whatlinkshere' => 'Bu sahypa çykgyt berýän ähli wiki sahypalarynyň sanawy',
-'tooltip-t-recentchangeslinked' => 'Bu sahypa çykgyt berýän sahypalardaky soňky üýtgeşmeler',
+'tooltip-n-recentchanges' => 'Wikidäki soňky üýtgetmeleriň sanawy',
+'tooltip-n-randompage' => 'Çem gelen sahypany aç',
+'tooltip-n-help' => 'Kömek soralýan ýer',
+'tooltip-t-whatlinkshere' => 'Şu ýere çykgyt berýän ähli wiki-sahypalaryň sanawy',
+'tooltip-t-recentchangeslinked' => 'Bu sahypadan çykgyt alýan sahypalardaky soňky üýtgetmeler',
 'tooltip-feed-rss' => 'Bu sahypa üçin RSS lentasy',
-'tooltip-feed-atom' => 'Bu sahypa üçin atom lentasy',
+'tooltip-feed-atom' => 'Bu sahypanyň atom lentasy',
 'tooltip-t-contributions' => 'Şu ulanyjynyň goşantlarynyň sanawyny gör',
 'tooltip-t-emailuser' => 'Bu ulanyja e-poçta iber',
-'tooltip-t-upload' => 'Suratlary ýa-da multimediýa faýllaryny ýükläň',
-'tooltip-t-specialpages' => 'Ähli ýörite sahypalaryň sanawyny görkez',
-'tooltip-t-print' => 'Bu sahypanyň print etmäge taýýar wersiýasy',
-'tooltip-t-permalink' => 'Sahypanyň bu wersiýasyna hemişelik çykgyt',
-'tooltip-ca-nstab-main' => 'Sahypany görkez',
+'tooltip-t-upload' => 'Faýllary ýükle',
+'tooltip-t-specialpages' => 'Ähli ýörite sahypalaryň sanawy',
+'tooltip-t-print' => 'Bu sahypanyň çap edilýän wersiýasy',
+'tooltip-t-permalink' => 'Sahypanyň şu wersiýasyna hemişelik çykgyt',
+'tooltip-ca-nstab-main' => 'Esasy sahypany gör',
 'tooltip-ca-nstab-user' => 'Ulanyjynyň sahypasyny görkez',
 'tooltip-ca-nstab-media' => 'Media sahypasyny görkez',
 'tooltip-ca-nstab-special' => 'Bu ýörite sahypa, ony redaktirläp bolmaýar',
 'tooltip-ca-nstab-project' => 'Taslama sahypasyny görkez',
-'tooltip-ca-nstab-image' => 'Suratyň sahypasyny görkez',
+'tooltip-ca-nstab-image' => 'Faýlyň sahypasyny gör',
 'tooltip-ca-nstab-mediawiki' => 'Ulgam habarlaşygyny görkez',
 'tooltip-ca-nstab-template' => 'Şablony görkez',
 'tooltip-ca-nstab-help' => 'Ýardam sahypasyny görkez',
-'tooltip-ca-nstab-category' => 'Kategoriýanyň sahypasyny görkez',
+'tooltip-ca-nstab-category' => 'Kategoriýanyň sahypasyny gör',
 'tooltip-minoredit' => 'Ujypsyzja özgerdiş hökmünde belle',
 'tooltip-save' => 'Özgerdişleriňi ýazdyr',
 'tooltip-preview' => 'Deslapky syn; ýazdyrmankaňyz şuny ulanyp özgerdişleriňizi gözden geçiriň!',
@@ -2410,8 +2410,7 @@ Onuň çeşmesini görüp bilersiňiz',
 'tooltip-recreate' => 'Öçürilendigine garamazdan sahypany gaýtadan döret',
 'tooltip-upload' => 'Ýüklemäni başlat',
 'tooltip-rollback' => '"Öňki katdyna getir" ýeke gezek tyklananda bu sahypa iň soňky goşant goşanyň özgerdişlerini yzyna getirýär',
-'tooltip-undo' => '"Yzyna al" bu özgerdişi yzyna getirýär we özgerdiş formuny deslapky syn modunda açýar.
-Mazmun üçin bir sebäp goşmaga rugsat berýär',
+'tooltip-undo' => '"Yzyna al" bu özgerdişi yzyna getirýär we özgerdiş formuny synlaw modunda açýar. Yzyna almagyň sebäbini ýazmaga mümkinçilik berýär.',
 'tooltip-preferences-save' => 'Ileri tutmalary ýazdyr',
 'tooltip-summary' => 'Gysgaça düşündiriş giriziň',
 
@@ -2481,7 +2480,7 @@ Ony işletseňiz iş ulgamyňyza howp astyna salmagyňyz mümkin.",
 'file-info-size' => '$1 × $2 piksel, faýlyň ölçegi: $3, MIME tipli: $4',
 'file-nohires' => 'Wersiýanyň mundan uly ölçegi ýok.',
 'svg-long-desc' => 'SVG faýly, nominal $1 × $2 piksel, faýl ölçegi: $3',
-'show-big-image' => 'Suratyň doly ölçegi',
+'show-big-image' => 'Original faýl',
 'file-info-gif-looped' => 'halkaly',
 'file-info-gif-frames' => '$1 {{PLURAL:$1|kadr|kadr}}',
 'file-info-png-looped' => 'halkaly',
@@ -2504,7 +2503,7 @@ Ony işletseňiz iş ulgamyňyza howp astyna salmagyňyz mümkin.",
 'bad_image_list' => 'Format aşakdaky ýaly bolmalydyr:
 
 Diňe sanawyň elementleri (* bilen başlaýanlar) nazara alynýar. Setirdäki ilkinji çykgyt ýaramaz suratyň çykgydy bolmalydyr.
-Ondan soňraky çykgyt(lar) kadadan çykma hökmünde kabul edilýär, meselem: surat sahypada setiriçinde görünip biler.',
+Ondan soňraky çykgyt(lar) kadadan çykma hökmünde kabul edilýär, meselem: surat sahypada setiriçinde görp biler.',
 
 # Metadata
 'metadata' => 'Meta-maglumat',
index 7275cec..0fe0f7d 100644 (file)
@@ -560,15 +560,15 @@ Tandaan na may ilang pahinang maaaring magpatuloy na nagpapakitang parang nakala
 Huwag kalimutang baguhin ang iyong [[Special:Preferences|mga kagustuhan sa {{SITENAME}}]].',
 'yourname' => 'Bansag:',
 'userlogin-yourname' => 'Pangngalan',
-'userlogin-yourname-ph' => 'Ilagay ang iyong Pangngalan',
-'createacct-another-username-ph' => 'Ilagay ang Pangngalan',
+'userlogin-yourname-ph' => 'Ilagay ang iyong Pangalan',
+'createacct-another-username-ph' => 'Ilagay ang Pangalan',
 'yourpassword' => 'Hudyat:',
 'userlogin-yourpassword' => 'Hudyat',
 'userlogin-yourpassword-ph' => 'Ipasok ang iyong hudyat',
-'createacct-yourpassword-ph' => 'Ilagay ang hudyat',
+'createacct-yourpassword-ph' => 'Ilagay ang hudyat (password)',
 'yourpasswordagain' => 'Hudyat mo uli:',
 'createacct-yourpasswordagain' => 'Tiyakin ang hudyat',
-'createacct-yourpasswordagain-ph' => 'Muling ilagay ang hudyat',
+'createacct-yourpasswordagain-ph' => 'Muling ilagay ang hudyat (password)',
 'remembermypassword' => 'Tandaan ang paglagda ko sa kompyuter na ito (pinakamarami na ang $1 {{PLURAL:$1|araw|mga araw}})',
 'userlogin-remembermypassword' => 'Panatilihin akong nakalagda',
 'userlogin-signwithsecure' => 'Gumamit ng ligtas na koneksyon',
@@ -591,7 +591,7 @@ Huwag kalimutang baguhin ang iyong [[Special:Preferences|mga kagustuhan sa {{SIT
 'gotaccount' => 'May kuwenta ka na ba? $1.',
 'gotaccountlink' => 'Lumagda',
 'userlogin-resetlink' => 'Nakalimutan mo ang iyong mga detalyeng panglagda?',
-'userlogin-resetpassword-link' => 'Nakalimutan ba ang iyong hudyat?',
+'userlogin-resetpassword-link' => 'Nakalimutan ba ang iyong hudyat (password)?',
 'userlogin-createanother' => 'Lumikha ng iba pang akawnt',
 'createacct-join' => 'Ilagay ang iyong impormasyon sa ibaba.',
 'createacct-another-join' => 'Ilagay ang impormasyon ng bagong akawnt sa ibaba.',
index 200d21c..f687869 100644 (file)
@@ -2580,10 +2580,10 @@ dikkatle devam edin.',
 'rollbacklinkcount-morethan' => '$1 {{PLURAL:$1|değişiklikten|değişiklikten}} fazla geri döndür',
 'rollbackfailed' => 'geri alma işlemi başarısız',
 'cantrollback' => 'Sayfaya son katkıda bulunan kullanıcı, sayfaya katkıda bulunmuş tek kişi olduğu için, değişiklikler geri alınamıyor.',
-'alreadyrolled' => '[[User:$2|$2]] ([[User talk:$2|Talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tarafından [[:$1]] sayfasında yapılmış son değişiklik geriye alınamıyor;
-başka biri sayfada değişiklik yaptı ya da sayfayı geriye aldı.
+'alreadyrolled' => '[[User:$2|$2]] ([[User talk:$2|Tartışma]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tarafından [[:$1]] sayfasında yapılmış son değişiklik geriye alınamıyor;
+başka birisi sayfada değişiklik yaptı ya da sayfayı geriye aldı.
 
-Son değişikliği yapan: [[User:$3|$3]] ([[User talk:$3|Talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
+Son değişikliği yapan: [[User:$3|$3]] ([[User talk:$3|Tartışma]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
 'editcomment' => "Değişiklik özeti: \"''\$1''\" idi.",
 'revertpage' => '[[Special:Contributions/$2|$2]] [[User talk:$2|mesaj]] tarafından yapılan değişiklikler geri alınarak, [[User:$1|$1]] tarafından değiştirilmiş önceki sürüm geri getirildi.',
 'revertpage-nouser' => 'Gizli bir kullanıcı tarafından yapılan değişiklikler geri alınarak {{GENDER:$1|[[User:$1|$1]]}} tarafından yapılan son revizyon geri getirildi',
index f854fd2..06c92c1 100644 (file)
@@ -947,7 +947,7 @@ $1',
 'resetpass-temp-password' => 'Тимчасовий пароль:',
 'resetpass-abort-generic' => 'Зміну пароля було перервано розширенням.',
 'resetpass-expired' => 'Термін дії вашого пароля закінчився. Будь ласка, встановіть новий пароль для входу в систему.',
-'resetpass-expired-soft' => 'Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть «Скасувати», щоб змінити його пізніше.',
+'resetpass-expired-soft' => 'Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть "{{int:resetpass-submit-cancel}}", щоб змінити його пізніше.',
 
 # Special:PasswordReset
 'passwordreset' => 'Скинути пароль',
@@ -1962,6 +1962,7 @@ $1",
 'uploaddisabledtext' => 'Можливість завантаження файлів відключена.',
 'php-uploaddisabledtext' => 'Завантаження файлів вимкнене у налаштуваннях PHP. Будь ласка, перевірте значення file_uploads.',
 'uploadscripted' => 'Файл містить HTML-код або скрипт, який може неправильно обробитися браузером.',
+'uploadscriptednamespace' => 'Цей SVG-файл містить недопустимий простір імен "$1"',
 'uploadinvalidxml' => 'Не вдалося проаналізувати XML у завантаженому файлі.',
 'uploadvirus' => 'Файл містить вірус! Див. $1',
 'uploadjava' => 'Файл є ZIP-архівом, що містить .class-файл Java.
@@ -2793,8 +2794,10 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'Доступ з цієї IP-адреси зараз заблокований.
 Далі наведено останній запис з журналу блокувань:',
 'sp-contributions-search' => 'Пошук внеску',
+'sp-contributions-suppresslog' => 'вилучений внесок користувача',
 'sp-contributions-username' => "IP-адреса або ім'я користувача:",
 'sp-contributions-toponly' => 'Показувати тільки редагування, що є останніми версіями',
+'sp-contributions-newonly' => 'Показувати тільки редагування, які є створеннями сторінок',
 'sp-contributions-submit' => 'Знайти',
 
 # What links here
index d9240ce..892df9c 100644 (file)
@@ -190,18 +190,18 @@ $messages = array(
 'october' => 'oktabr',
 'november' => 'noyabr',
 'december' => 'dekabr',
-'january-gen' => 'yanvarning',
-'february-gen' => 'fevralning',
-'march-gen' => 'martning',
-'april-gen' => 'aprelning',
-'may-gen' => 'mayning',
-'june-gen' => 'iyunning',
-'july-gen' => 'iyulning',
-'august-gen' => 'avgustning',
-'september-gen' => 'sentabrning',
-'october-gen' => 'oktabrning',
-'november-gen' => 'noyabrning',
-'december-gen' => 'dekabrning',
+'january-gen' => 'yanvar',
+'february-gen' => 'fevral',
+'march-gen' => 'mart',
+'april-gen' => 'aprel',
+'may-gen' => 'may',
+'june-gen' => 'iyun',
+'july-gen' => 'iyul',
+'august-gen' => 'avgust',
+'september-gen' => 'sentabr',
+'october-gen' => 'oktabr',
+'november-gen' => 'noyabr',
+'december-gen' => 'dekabr',
 'jan' => 'yan',
 'feb' => 'fev',
 'mar' => 'mar',
@@ -214,6 +214,17 @@ $messages = array(
 'oct' => 'okt',
 'nov' => 'noy',
 'dec' => 'dek',
+'january-date' => 'Yanvar $1',
+'february-date' => 'Fevral $1',
+'march-date' => 'Mart $1',
+'april-date' => 'Aprel $1',
+'june-date' => 'Iyun $1',
+'july-date' => 'Iyul $1',
+'august-date' => 'Avgust $1',
+'september-date' => 'Sentabr $1',
+'october-date' => 'Oktabr $1',
+'november-date' => 'Noyabr $1',
+'december-date' => 'Dekabr $1',
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|Turkum}}',
@@ -293,7 +304,8 @@ $messages = array(
 'create-this-page' => 'Ushbu sahifani yaratish',
 'delete' => 'O‘chirish',
 'deletethispage' => 'Ushbu sahifani o‘chirish',
-'undelete_short' => '$1 ta tahrirni tiklash',
+'undeletethispage' => 'Ushbu sahifani tiklash',
+'undelete_short' => '{{PLURAL:$1|bitta tahrir|$1 ta tahrir}}ni tiklash',
 'viewdeleted_short' => '$1 ta oʻchirilgan tahrirni koʻrish',
 'protect' => 'Himoyalash',
 'protect_change' => 'Oʻzgartirish',
@@ -339,7 +351,7 @@ $1',
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).
 'aboutsite' => '{{SITENAME}} haqida',
 'aboutpage' => 'Project:Haqida',
-'copyright' => 'Keltirilgan maʼlumotlar $1 orqali tarqatilmoqda.',
+'copyright' => 'Keltirilgan maʼlumotlar $1 orqali tarqatilmoqda (agar aksinchasi koʻrsatilmagan boʻlsa).',
 'copyrightpage' => '{{ns:project}}:Mualliflik huquqlari',
 'currentevents' => 'Joriy hodisalar',
 'currentevents-url' => 'Project:Joriy hodisalar',
@@ -518,6 +530,8 @@ Ism yozilishini tekshirib koʻring.',
 'accountcreated' => 'Hisob yozuvi yaratildi',
 'login-abort-generic' => 'Tizimga kirishga mufavvaqiyatsiz urinish',
 'loginlanguagelabel' => 'Til: $1',
+'pt-login' => 'Kirish',
+'pt-userlogout' => 'Chiqish',
 
 # Change password dialog
 'changepassword' => 'Maxfiy soʻzni oʻzgartirish',
@@ -954,7 +968,7 @@ Agar keltirsangiz, undan sahifa kim tomonidan tahrirlanganini koʻrsatish uchun
 'recentchanges-label-plusminus' => 'vazni qanchaga oʻzgargani (bayt)',
 'recentchanges-legend-heading' => "'''Izoh:'''",
 'recentchanges-legend-newpage' => '([[Special:NewPages|alohida roʻyxat]])',
-'rcnotefrom' => "Quyida <strong>$2</strong> dan (<strong>$1</strong> gacha) bo'lgan o'zgarishlar keltirilgan.",
+'rcnotefrom' => 'Quyida <strong>$2</strong>dan boshlab boʻlgan oʻzgarishlar keltirilgan (<strong>$1</strong>dan koʻp boʻlmaganlari koʻrsatildi).',
 'rclistfrom' => '$1 dan boshlab yangi oʻzgarishlarni koʻrsat.',
 'rcshowhideminor' => 'Kichik tahrirlarni $1',
 'rcshowhidebots' => 'Botlarni $1',
@@ -1026,6 +1040,8 @@ Quyida bu sahifaga oid yoʻqotish va koʻchirish qaydlari keltirilgan:',
 'listfiles_size' => 'Oʻlchami',
 'listfiles_description' => 'Taʼrif',
 'listfiles_count' => 'Versiyalar',
+'listfiles-latestversion-yes' => 'Ha',
+'listfiles-latestversion-no' => 'Yoʻq',
 
 # File description page
 'file-anchor-link' => 'Fayl',
@@ -1069,6 +1085,9 @@ Uning [$2 fayl tavsifi sahifasidan] olingan tavsifi quyida keltirilgan.',
 # Random page
 'randompage' => 'Tasodifiy sahifa',
 
+# Random page in category
+'randomincategory-selectcategory-submit' => 'Oʻtish',
+
 # Statistics
 'statistics' => 'Statistika',
 'statistics-header-pages' => 'Sahifalar statistikasi',
@@ -1084,6 +1103,9 @@ Uning [$2 fayl tavsifi sahifasidan] olingan tavsifi quyida keltirilgan.',
 'statistics-users-active' => 'Faol foydalanuvchilar',
 'statistics-users-active-desc' => 'Oxirgi $1 kun ichida kamida bitta amal qilgan foydalanuvchilar',
 
+'pageswithprop-prop' => 'Xossa nomi:',
+'pageswithprop-submit' => 'Oʻtish',
+
 # Miscellaneous special pages
 'nbytes' => '$1 {{PLURAL:$1|bayt}}',
 'ncategories' => '$1 {{PLURAL:$1|turkum|turkumlar}}',
index 3ab410c..f3e2119 100644 (file)
@@ -866,7 +866,7 @@ Xin hãy bỏ qua thông điệp này nếu tài khoản này không phải do b
 
 Nếu bạn đồng ý cung cấp, nó sẽ dùng để ghi nhận công lao của bạn.',
 'pt-login' => 'Đăng nhập',
-'pt-createaccount' => 'Tạo tài khoản',
+'pt-createaccount' => 'Mở tài khoản',
 'pt-userlogout' => 'Đăng xuất',
 
 # Email sending
@@ -896,7 +896,7 @@ Có thể bạn đã thay đổi thành công mật khẩu của mình hoặc đ
 'resetpass-temp-password' => 'Mật khẩu tạm:',
 'resetpass-abort-generic' => 'Một phần mở rộng đã hủy bỏ tác vụ thay đổi mật khẩu.',
 'resetpass-expired' => 'Mật khẩu của bạn đã hết hạn. Xin vui lòng tạo lại mật khẩu mới để đăng nhập.',
-'resetpass-expired-soft' => 'Mật khẩu của bạn đã hết hạn và cần được đặt lại. Xin vui lòng chọn một mật khẩu mới lúc bây giờ hoặc bấm Hủy bỏ để đặt lại sau.',
+'resetpass-expired-soft' => 'Mật khẩu của bạn đã hết hạn và cần được đặt lại. Xin vui lòng chọn một mật khẩu mới lúc bây giờ hoặc bấm “{{int:resetpass-submit-cancel}}” để đặt lại sau.',
 
 # Special:PasswordReset
 'passwordreset' => 'Tái tạo mật khẩu',
@@ -1746,7 +1746,7 @@ Nếu bạn đồng ý cung cấp, nó sẽ dùng để ghi nhận công lao c
 'recentchanges-legend-heading' => "'''Chú giải:'''",
 'recentchanges-legend-newpage' => '(xem thêm [[Special:NewPages|danh sách các trang mới]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "Thay đổi từ '''$2''' (hiển thị tối đa '''$1''' thay đổi).",
+'rcnotefrom' => 'Thay đổi từ <strong>$2</strong> (hiển thị tối đa <strong>$1</strong> thay đổi).',
 'rclistfrom' => 'Hiển thị các thay đổi từ $1.',
 'rcshowhideminor' => '$1 sửa đổi nhỏ',
 'rcshowhideminor-show' => 'Hiện',
@@ -1758,8 +1758,14 @@ Nếu bạn đồng ý cung cấp, nó sẽ dùng để ghi nhận công lao c
 'rcshowhideliu-show' => 'Hiện',
 'rcshowhideliu-hide' => 'Ẩn',
 'rcshowhideanons' => '$1 sửa đổi vô danh',
+'rcshowhideanons-show' => 'Hiện',
+'rcshowhideanons-hide' => 'Ẩn',
 'rcshowhidepatr' => '$1 sửa đổi đã tuần tra',
+'rcshowhidepatr-show' => 'Hiện',
+'rcshowhidepatr-hide' => 'Ẩn',
 'rcshowhidemine' => '$1 sửa đổi của tôi',
+'rcshowhidemine-show' => 'Hiện',
+'rcshowhidemine-hide' => 'Ẩn',
 'rclinks' => 'Xem $1 sửa đổi gần đây nhất trong $2 ngày qua; $3.',
 'diff' => 'khác',
 'hist' => 'sử',
@@ -1886,6 +1892,7 @@ Bạn nên xin một người có quyền xem dữ liệu tập tin bị đàn 
 'uploaddisabledtext' => 'Chức năng tải tập tin đã bị tắt.',
 'php-uploaddisabledtext' => 'Việc tải tập tin trong PHP đã bị tắt. Xin hãy kiểm tra lại thiết lập file_uploads.',
 'uploadscripted' => 'Tập tin này có chứa mã HTML hoặc kịch bản có thể khiến trình duyệt web thông dịch sai.',
+'uploadscriptednamespace' => 'Tập tin SVG này chứa không gian tên “$1” không được cho phép',
 'uploadinvalidxml' => 'Không thể phân tích mã XML trong tập tin tải lên.',
 'uploadvirus' => 'Tập tin có virút! Chi tiết: $1',
 'uploadjava' => 'Tập tin ZIP này chứa một tập tin Java .class.
@@ -2716,6 +2723,7 @@ $1',
 'sp-contributions-search' => 'Tìm kiếm đóng góp',
 'sp-contributions-username' => 'Địa chỉ IP hay tên thành viên:',
 'sp-contributions-toponly' => 'Chỉ hiện các phiên bản mới nhất',
+'sp-contributions-newonly' => 'Chỉ hiện các sửa đổi tạo trang',
 'sp-contributions-submit' => 'Tìm kiếm',
 
 # What links here
index 66e7f42..e7e8770 100644 (file)
@@ -758,7 +758,7 @@ $2',
 
 # Change password dialog
 'changepassword' => 'טוישן פאַסווארט',
-'resetpass_announce' => '×\90×\99ר ×\94×\90×\98 ×\90ר×\99×\99× ×\9c×\90×\92×\99ר×\98 ×\9e×\99×\98 ×\90 ×¤×¨×\90×\95×\95×\99×\96×\90ר×\99ש×\9f ×§×\90×\93 ×\92עש×\99ק×\98 ×\93×\95ר×\9b×\9f ×¢-פ×\90ס×\98. ×¦×\95 ×¤×\90רענ×\93×\99×\92×\9f ×\90ר×\99×\99× ×\9c×\90×\92×\99ר×\9f, ×\91ר×\95×\99×\9b×\98 ×\90×\99ר ×\90נש×\98×¢×\9c×\9f ×\90 × ×\99×\99 ×¤×\90ס×\95×\95×\90ר×\98 ×\93×\90:',
+'resetpass_announce' => 'צו פארענדיגן אריינלאגירן, ברויכט איר אנשטעלן א ניי פאסווארט דא:',
 'resetpass_text' => '<!-- לייגט צו טעקסט דא -->',
 'resetpass_header' => 'ענדערן קאנטע פאסווארט',
 'oldpassword' => 'אַלטע פאַסווארט:',
@@ -774,6 +774,7 @@ $2',
 'resetpass-submit-cancel' => 'אַנולירן',
 'resetpass-wrong-oldpass' => 'אומגילטיג צײַטווײַליק אדער לויפֿיק פאַסווארט.
 איר האט מעגלעך שוין געטוישט אייער פאַסווארט מיט הצלחה אדער געבעטן א נײַ  צײַטווײַליק פאַסווארט.',
+'resetpass-recycled' => 'זײַט אזוי גוט שטעטל אירע פאסווארט צו עפעס אנדערש פונעם לויפיקן פאסווארט.',
 'resetpass-temp-password' => 'צײַטווייליק פאַסווארט:',
 'resetpass-abort-generic' => 'פאסווארט ענדערונג איז מבוטל געווארן דורך א פארברייטערונג.',
 
@@ -1260,6 +1261,7 @@ $1",
 'showhideselectedversions' => 'ווײַזן/באַהאַלטן געקליבענע רעוויזיעס',
 'editundo' => 'אַנולירן',
 'diff-empty' => '(קיין אונטערשייד)',
+'diff-multi-sameuser' => '({{PLURAL:$1|איין צווישנדיקע ווערסיע |$1 צווישנדיקע ווערסיעס}} פֿונעם זעלבן באַניצער נישט געוויזן.)',
 'diff-multi-otherusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון {{PLURAL:$2|איין אנדער באַניצער|$2 באַניצער}} נישט געוויזן.)',
 'diff-multi-manyusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון מער ווי {{PLURAL:$2|איין באַניצער|$2 באַניצער}} נישט געוויזן.)',
 'difference-missing-revision' => '{{PLURAL:$2|איין ווערסיע|$2 ווערסיעס}} פון דעם דיפערענץ ($1) {{PLURAL:$2|האט}} מען נישט געטראפן.
@@ -1625,9 +1627,10 @@ $1",
 'recentchanges-legend-heading' => "'''לעגענדע:'''",
 'recentchanges-legend-newpage' => '(זעט אויך [[Special:NewPages|די רשימה פון נייע בלעטער]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "פֿאלגנד זענען די ענדערונגען זײַט '''$2''' (ביז '''$1''')",
+'rcnotefrom' => 'פֿאלגנד זענען די ענדערונגען זײַט <strong>$2</strong> (ביז <strong>$1</strong>).',
 'rclistfrom' => 'װײַזן נײַע ענדערונגען פֿון $1',
 'rcshowhideminor' => '$1 מינערדיגע ענדערונגען',
+'rcshowhideminor-hide' => 'באהאלטן',
 'rcshowhidebots' => '$1 ראבאטן',
 'rcshowhidebots-show' => 'ווײַזן',
 'rcshowhidebots-hide' => 'באַהאַלטן',
index ff1e984..658b6fa 100644 (file)
@@ -689,6 +689,7 @@ $1',
 'login-throttled' => '你已經試咗太多次登入動作。請等多一陣再試過。',
 'loginlanguagelabel' => '語言:$1',
 'suspicious-userlogout' => '你去登出嘅要求已經拒絕咗,因為佢可能由壞咗嘅瀏覽器或者快取代理傳送。',
+'pt-createaccount' => '開戶口',
 
 # Email sending
 'php-mail-error-unknown' => '響 PHP 嘅 mail() 參數度出現咗未知嘅錯誤',
index fc2f23d..aa8ca0a 100644 (file)
@@ -938,7 +938,7 @@ $2',
 'resetpass-temp-password' => '临时密码:',
 'resetpass-abort-generic' => '密码更改已被一个扩展插件中止。',
 'resetpass-expired' => '您的密码已经过期。请设置一个新的密码登录。',
-'resetpass-expired-soft' => '您的密码已经过期,并且需要重置。请现在选择一个新密码,或单击取消以便稍后重置。',
+'resetpass-expired-soft' => '您的密码已过期并且需要重置。请现在选择一个新密码,或单击“{{int:resetpass-submit-cancel}}”以便稍后重置。',
 
 # Special:PasswordReset
 'passwordreset' => '重置密码',
@@ -1722,7 +1722,7 @@ $1",
 'recentchanges-legend-heading' => "'''说明:'''",
 'recentchanges-legend-newpage' => '(另见[[Special:NewPages|新页面列表]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "下面是'''$2'''之后的更改(最多显示'''$1'''个)。",
+'rcnotefrom' => '下面是<strong>$2</strong>之后的更改(最多显示<strong>$1</strong>个)。',
 'rclistfrom' => '显示$1之后的新更改',
 'rcshowhideminor' => '$1小编辑',
 'rcshowhideminor-show' => '显示',
@@ -2645,6 +2645,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => '这个IP地址现时正在被封锁中。
 最近的封锁日志项目在下面提供以便参考:',
 'sp-contributions-search' => '搜索贡献',
+'sp-contributions-suppresslog' => '已被删除的用户贡献',
 'sp-contributions-username' => 'IP地址或用户名:',
 'sp-contributions-toponly' => '仅显示最后版本的编辑',
 'sp-contributions-newonly' => '仅显示创建页面的编辑',
index ba2f515..62f4b80 100644 (file)
@@ -837,7 +837,7 @@ $2',
 'resetpass-temp-password' => '臨時密碼:',
 'resetpass-abort-generic' => '擴充元件已中止了更改密碼操作。',
 'resetpass-expired' => '您的密碼已過期。請設置新密碼以登錄。',
-'resetpass-expired-soft' => '您的密碼已過期,現需重置。請設置新密碼以登錄,或點擊取消以稍後重置。',
+'resetpass-expired-soft' => '您的密碼已過期,現需重置。請設置新密碼以登錄,或點擊“{{int:resetpass-submit-cancel}}”以稍後重置。',
 
 # Special:PasswordReset
 'passwordreset' => '重新設定密碼',
@@ -1657,7 +1657,7 @@ $1",
 'recentchanges-legend-heading' => "'''說明:'''",
 'recentchanges-legend-newpage' => '(另見[[Special:NewPages|新頁面列表]])',
 'recentchanges-legend-plusminus' => "(''±123'')",
-'rcnotefrom' => "下面是自'''$2'''(最多顯示'''$1'''):",
+'rcnotefrom' => '下面是自<strong>$2</strong>起之更改(至多顯示<strong>$1</strong>個)。',
 'rclistfrom' => '顯示自 $1 以來的新變更',
 'rcshowhideminor' => '$1小編輯',
 'rcshowhideminor-show' => '顯示',
@@ -2606,6 +2606,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => '這個IP地址現時正在被封鎖中。
 最近的封鎖日誌項目在下面提供以便參考:',
 'sp-contributions-search' => '搜尋貢獻記錄',
+'sp-contributions-suppresslog' => '已隱藏的用戶貢獻',
 'sp-contributions-username' => 'IP位址或用戶名稱:',
 'sp-contributions-toponly' => '只顯示最新修訂版本的編輯',
 'sp-contributions-newonly' => '僅顯示建立頁面之編輯',
index d97a4cd..074d440 100644 (file)
@@ -2254,6 +2254,7 @@ $wgMessageStructure = array(
                'sp-contributions-blocked-notice',
                'sp-contributions-blocked-notice-anon',
                'sp-contributions-search',
+               'sp-contributions-suppresslog',
                'sp-contributions-username',
                'sp-contributions-toponly',
                'sp-contributions-newonly',
index 4c6a7ac..6689b7c 100644 (file)
@@ -20,7 +20,7 @@
                 *
                 * @param {Object} nav An object with atleast a 'userAgent' and 'platform' key.
                 * Defaults to the global Navigator object.
-                * @returns {Object} The resulting client object will be in the following format:
+                * @return {Object} The resulting client object will be in the following format:
                 *  {
                 *   'name': 'firefox',
                 *   'layout': 'gecko',
                 * @param {boolean} [exactMatchOnly=false] Only return true if the browser is matched, otherwise
                 * returns true if the browser is not found.
                 *
-                * @returns {boolean} The current browser is in the support map
+                * @return {boolean} The current browser is in the support map
                 */
                test: function ( map, profile, exactMatchOnly ) {
                        /*jshint evil: true */
index 8bc45c9..04f8047 100644 (file)
@@ -14,7 +14,7 @@
                var color;
 
                do {
-                       color = $.curCSS( elem, attr );
+                       color = $.css( elem, attr );
 
                        // Keep going until we find an element that has color, or we hit the body
                        if ( color !== '' && color !== 'transparent' || $.nodeName( elem, 'body' ) ) {
                'outlineColor'
        ], function ( i, attr ) {
                $.fx.step[attr] = function ( fx ) {
-                       if ( fx.state === 0 ) {
+                       if ( !fx.colorInit ) {
                                fx.start = getColor( fx.elem, attr );
                                fx.end = $.colorUtil.getRGB( fx.end );
+                               fx.colorInit = true;
                        }
 
                        fx.elem.style[attr] = 'rgb(' + [
index 70bfc4e..eb29db9 100644 (file)
@@ -16,8 +16,7 @@
  *
  * Uses window.devicePixelRatio if available, or CSS media queries on IE.
  *
- * @method
- * @returns {number} Device pixel ratio
+ * @return {number} Device pixel ratio
  */
 $.devicePixelRatio = function () {
        if ( window.devicePixelRatio !== undefined ) {
@@ -51,8 +50,7 @@ $.devicePixelRatio = function () {
  * Implement responsive images based on srcset attributes, if browser has no
  * native srcset support.
  *
- * @method
- * @returns {jQuery} This selection
+ * @return {jQuery} This selection
  */
 $.fn.hidpi = function () {
        var $target = this,
@@ -81,11 +79,11 @@ $.fn.hidpi = function () {
 /**
  * Match a srcset entry for the given device pixel ratio
  *
+ * Exposed for testing.
+ *
  * @param {number} devicePixelRatio
  * @param {string} srcset
  * @return {mixed} null or the matching src string
- *
- * Exposed for testing.
  */
 $.matchSrcSet = function ( devicePixelRatio, srcset ) {
        var candidates,
index d9a2b19..e0d9de2 100644 (file)
@@ -9,7 +9,7 @@
  *
  * @param {Object} options
  * @param {string} key
- * @returns {string} Localized message
+ * @return {string} Localized message
  */
 function msg( options, key ) {
        var args = options.params[key] || [];
index d61c1c6..57eda3d 100644 (file)
@@ -3,6 +3,7 @@
  */
 ( function ( mw, $ ) {
 
+       var msg = 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.';
        $.extend( mw.Api.prototype, {
                /**
                 * Determine if a category exists.
                                apiPromise;
 
                        // Backwards compatibility (< MW 1.20)
-                       d.done( ok ).fail( err );
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                               d.done( ok ).fail( err );
+                       }
 
                        apiPromise = this.get( {
                                        prop: 'categoryinfo',
                                apiPromise;
 
                        // Backwards compatibility (< MW 1.20)
-                       d.done( ok ).fail( err );
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                               d.done( ok ).fail( err );
+                       }
 
                        // Fetch with allpages to only get categories that have a corresponding description page.
                        apiPromise = this.get( {
                                apiPromise;
 
                        // Backwards compatibility (< MW 1.20)
-                       d.done( ok ).fail( err );
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                               d.done( ok ).fail( err );
+                       }
 
                        apiPromise = this.get( {
                                        prop: 'categories',
index cc83a4b..91d9b8f 100644 (file)
@@ -3,6 +3,7 @@
  */
 ( function ( mw, $ ) {
 
+       var msg = 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.';
        $.extend( mw.Api.prototype, {
 
                /**
                 * @return {jQuery.Promise} See #post
                 */
                postWithEditToken: function ( params, ok, err ) {
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                       }
                        return this.postWithToken( 'edit', params ).done( ok ).fail( err );
                },
 
                /**
                 * Api helper to grab an edit token.
                 *
-                * @param {Function} [ok] Success callback
-                * @param {Function} [err] Error callback
+                * @param {Function} [ok] Success callback (deprecated)
+                * @param {Function} [err] Error callback (deprecated)
                 * @return {jQuery.Promise}
                 * @return {Function} return.done
                 * @return {string} return.done.token Received token.
                 */
                getEditToken: function ( ok, err ) {
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                       }
                        return this.getToken( 'edit' ).done( ok ).fail( err );
                },
 
                 * @param {mw.Title|String} title Target page
                 * @param {string} header
                 * @param {string} message wikitext message
-                * @param {Function} [ok] Success handler
-                * @param {Function} [err] Error handler
+                * @param {Function} [ok] Success handler (deprecated)
+                * @param {Function} [err] Error handler (deprecated)
                 * @return {jQuery.Promise}
                 */
                newSection: function ( title, header, message, ok, err ) {
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
+                       }
                        return this.postWithEditToken( {
                                action: 'edit',
                                section: 'new',
@@ -50,7 +63,7 @@
                                title: title.toString(),
                                summary: header,
                                text: message
-                       }, ok, err );
+                       } ).done( ok ).fail( err );
                }
        } );
 
index 0024f4b..7490862 100644 (file)
                ajax: function ( parameters, ajaxOptions ) {
                        var token,
                                apiDeferred = $.Deferred(),
+                               msg = 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.',
                                xhr;
 
                        parameters = $.extend( {}, this.defaults.parameters, parameters );
                        // Backwards compatibility: Before MediaWiki 1.20,
                        // callbacks were done with the 'ok' and 'err' property in ajaxOptions.
                        if ( ajaxOptions.ok ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
                                apiDeferred.done( ajaxOptions.ok );
                                delete ajaxOptions.ok;
                        }
                        if ( ajaxOptions.err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( msg );
                                apiDeferred.fail( ajaxOptions.err );
                                delete ajaxOptions.err;
                        }
index c4d23b8..1c04b17 100644 (file)
                                apiPromise;
 
                        // Backwards compatibility (< MW 1.20)
-                       d.done( ok ).fail( err );
+                       if ( ok || err ) {
+                               mw.track( 'mw.deprecate', 'api.cbParam' );
+                               mw.log.warn( 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.' );
+                               d.done( ok ).fail( err );
+                       }
 
                        apiPromise = this.get( {
                                        action: 'parse',
index ab8a512..5a24247 100644 (file)
@@ -8,31 +8,46 @@
         * @private
         * @context mw.Api
         *
-        * @param {string|mw.Title|string[]|mw.Title[]} page Full page name or instance of mw.Title or array of pages
+        * @param {string|mw.Title|string[]|mw.Title[]} page Full page name or instance of mw.Title, or an
+        *  array thereof. If an array is passed, the return value passed to the promise will also be an
+        *  array of appropriate objects.
         * @param {Function} [ok] Success callback (deprecated)
         * @param {Function} [err] Error callback (deprecated)
         * @return {jQuery.Promise}
         * @return {Function} return.done
-        * @return {Object} return.done.watch
+        * @return {Object|Object[]} return.done.watch
         * @return {string} return.done.watch.title Full pagename
         * @return {boolean} return.done.watch.watched
         * @return {string} return.done.watch.message Parsed HTML of the confirmational interface message
         */
        function doWatchInternal( page, ok, err, addParams ) {
-               var params,
-                       d = $.Deferred(),
-                       apiPromise;
+               // XXX: Parameter addParams is undocumented because we inherit this
+               // documentation in the public method..
+               var params, apiPromise,
+                       d = $.Deferred();
 
                // Backwards compatibility (< MW 1.20)
-               d.done( ok ).fail( err );
+               if ( ok || err ) {
+                       mw.track( 'mw.deprecate', 'api.cbParam' );
+                       mw.log.warn( 'Use of mediawiki.api callback params is deprecated. Use the Promise instead.' );
+                       d.done( ok ).fail( err );
+               }
 
                params = {
                        action: 'watch',
-                       titles: $.isArray( page ) ? page.join( '|' ) : String( page ),
                        token: mw.user.tokens.get( 'watchToken' ),
                        uselang: mw.config.get( 'wgUserLanguage' )
                };
 
+               if ( $.isArray( page ) ) {
+                       params.titles = page.join( '|' );
+               } else {
+                       // The 'title' parameter is deprecated, keeping this for compatibility instead of
+                       // converting to array because the API response changes from object to array of objects
+                       // as well (bug 62422).
+                       params.title = String( page );
+               }
+
                if ( addParams ) {
                        $.extend( params, addParams );
                }
index 26f84f5..597f396 100644 (file)
@@ -381,7 +381,7 @@ var mw = ( function ( $, undefined ) {
                 * values with microsecond precision that are guaranteed to be monotonic. On all other browsers,
                 * it will fall back to using `Date`.
                 *
-                * @returns {number} Current time
+                * @return {number} Current time
                 */
                now: ( function () {
                        var perf = window.performance,
@@ -1405,7 +1405,7 @@ var mw = ( function ( $, undefined ) {
                                 */
                                work: function () {
                                        var     reqBase, splits, maxQueryLength, q, b, bSource, bGroup, bSourceGroup,
-                                               source, concatSource, group, g, i, modules, maxVersion, sourceLoadScript,
+                                               source, concatSource, origBatch, group, g, i, modules, maxVersion, sourceLoadScript,
                                                currReqBase, currReqBaseLength, moduleMap, l,
                                                lastDotIndex, prefix, suffix, bytesAdded, async;
 
@@ -1435,6 +1435,7 @@ var mw = ( function ( $, undefined ) {
                                        mw.loader.store.init();
                                        if ( mw.loader.store.enabled ) {
                                                concatSource = [];
+                                               origBatch = batch;
                                                batch = $.grep( batch, function ( module ) {
                                                        var source = mw.loader.store.get( module );
                                                        if ( source ) {
@@ -1443,7 +1444,29 @@ var mw = ( function ( $, undefined ) {
                                                        }
                                                        return true;
                                                } );
-                                               $.globalEval( concatSource.join( ';' ) );
+                                               try {
+                                                       $.globalEval( concatSource.join( ';' ) );
+                                               } catch ( err ) {
+                                                       // Not good, the cached mw.loader.implement calls failed! This should
+                                                       // never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
+                                                       // Depending on how corrupt the string is, it is likely that some
+                                                       // modules' implement() succeeded while the ones after the error will
+                                                       // never run and leave their modules in the 'loading' state forever.
+
+                                                       // Since this is an error not caused by an individual module but by
+                                                       // something that infected the implement call itself, don't take any
+                                                       // risks and clear everything in this cache.
+                                                       mw.loader.store.clear();
+                                                       // Re-add the ones still pending back to the batch and let the server
+                                                       // repopulate these modules to the cache.
+                                                       // This means that at most one module will be useless (the one that had
+                                                       // the error) instead of all of them.
+                                                       log( 'Error while evaluating data from mw.loader.store', err );
+                                                       origBatch = $.grep( origBatch, function ( module ) {
+                                                               return registry[module].state === 'loading';
+                                                       } );
+                                                       batch = batch.concat( origBatch );
+                                               }
                                        }
 
                                        // Early exit if there's nothing to load...
@@ -2093,6 +2116,14 @@ var mw = ( function ( $, undefined ) {
                                                }
                                        },
 
+                                       /**
+                                        * Clear the entire module store right now.
+                                        */
+                                       clear: function () {
+                                               mw.loader.store.items = {};
+                                               localStorage.removeItem( mw.loader.store.getStoreKey() );
+                                       },
+
                                        /**
                                         * Sync modules to localStorage.
                                         *
@@ -2355,6 +2386,7 @@ var mw = ( function ( $, undefined ) {
 }( jQuery ) );
 
 // Alias $j to jQuery for backwards compatibility
+// @deprecated since 1.23 Use $ or jQuery instead
 mw.log.deprecate( window, '$j', jQuery, 'Use $ or jQuery instead.' );
 
 // Attach to window and globally alias
index 959ea23..fe6ea0a 100644 (file)
@@ -9,5 +9,6 @@
     "ooui-dialog-action-close": "Zarrar",
     "ooui-outline-control-move-down": "Mover abaxo l'elementu",
     "ooui-outline-control-move-up": "Mover arriba l'elementu",
+    "ooui-outline-control-remove": "Desaniciar elementu",
     "ooui-toolbar-more": "Más"
 }
\ No newline at end of file
index fa9b1cf..55594c1 100644 (file)
@@ -4,5 +4,6 @@
             "ОйЛ"
         ]
     },
-    "ooui-dialog-action-close": "ꙁакрꙑи"
+    "ooui-dialog-action-close": "ꙁакрꙑи",
+    "ooui-toolbar-more": "вѧщє"
 }
\ No newline at end of file
index 173acd7..3f1ad0c 100644 (file)
@@ -9,11 +9,13 @@
             "Nojan Madinehi",
             "Reza1615",
             "Taha",
-            "درفش کاویانی"
+            "درفش کاویانی",
+            "Armin1392"
         ]
     },
     "ooui-dialog-action-close": "بستن",
     "ooui-outline-control-move-down": "انتقال مورد به پایین",
     "ooui-outline-control-move-up": "انتقال مورد به بالا",
+    "ooui-outline-control-remove": "حذف مورد",
     "ooui-toolbar-more": "بیشتر"
 }
\ No newline at end of file
index dcd367f..ce2f6d0 100644 (file)
@@ -19,5 +19,6 @@
     "ooui-dialog-action-close": "Sulje",
     "ooui-outline-control-move-down": "Siirrä kohdetta alaspäin",
     "ooui-outline-control-move-up": "Siirrä kohdetta ylöspäin",
+    "ooui-outline-control-remove": "Poista kohde",
     "ooui-toolbar-more": "Lisää"
 }
\ No newline at end of file
index 31b693c..404dc82 100644 (file)
@@ -18,5 +18,6 @@
     "ooui-dialog-action-close": "סגירה",
     "ooui-outline-control-move-down": "להזיז את הפריט מטה",
     "ooui-outline-control-move-up": "להזיז את הפריט מעלה",
+    "ooui-outline-control-remove": "הסרת פריט",
     "ooui-toolbar-more": "עוד"
 }
\ No newline at end of file
index f6cb90b..4cb8821 100644 (file)
@@ -8,5 +8,6 @@
     "ooui-dialog-action-close": "Փակել",
     "ooui-outline-control-move-down": "Իջեցնել կետը",
     "ooui-outline-control-move-up": "Բարձրացնել կետը",
+    "ooui-outline-control-remove": "Հեռացնել տարրը",
     "ooui-toolbar-more": "Ավելին"
 }
\ No newline at end of file
index efe0e67..fbdb5d1 100644 (file)
@@ -6,7 +6,7 @@
         ]
     },
     "ooui-dialog-action-close": "Loka",
-    "ooui-outline-control-move-down": "Færa atriða niður",
-    "ooui-outline-control-move-up": "Færa atriða upp",
+    "ooui-outline-control-move-down": "Færa atriði niður",
+    "ooui-outline-control-move-up": "Færa atriði upp",
     "ooui-toolbar-more": "Fleira"
 }
\ No newline at end of file
index f1f61df..25749ce 100644 (file)
@@ -11,5 +11,6 @@
     "ooui-dialog-action-close": "닫기",
     "ooui-outline-control-move-down": "항목을 아래로 옮기기",
     "ooui-outline-control-move-up": "항목을 위로 옮기기",
+    "ooui-outline-control-remove": "항목 지우기",
     "ooui-toolbar-more": "더 보기"
 }
\ No newline at end of file
index a18894e..6359026 100644 (file)
@@ -13,5 +13,6 @@
     "ooui-dialog-action-close": "Zoumaachen",
     "ooui-outline-control-move-down": "Element erof réckelen",
     "ooui-outline-control-move-up": "Element erop réckelen",
+    "ooui-outline-control-remove": "Element ewechhuelen",
     "ooui-toolbar-more": "Méi"
 }
\ No newline at end of file
index b3a16e8..db679bc 100644 (file)
@@ -2,8 +2,10 @@
     "@metadata": {
         "authors": [
             "Audriusa",
-            "Eitvys200"
+            "Eitvys200",
+            "Mantak111"
         ]
     },
-    "ooui-dialog-action-close": "Uždaryti"
+    "ooui-dialog-action-close": "Uždaryti",
+    "ooui-outline-control-remove": "Šalinti elementus"
 }
\ No newline at end of file
index 75db0a7..549fad2 100644 (file)
             "Saruman",
             "Siebrand",
             "Southparkfan",
-            "सरोज कुमार ढकाल"
+            "सरोज कुमार ढकाल",
+            "Sjoerddebruin"
         ]
     },
     "ooui-dialog-action-close": "Sluiten",
     "ooui-outline-control-move-down": "Item omlaag verplaatsen",
     "ooui-outline-control-move-up": "Item omhoog verplaatsen",
+    "ooui-outline-control-remove": "Item verwijderen",
     "ooui-toolbar-more": "Meer"
 }
\ No newline at end of file
index 424f1be..24a5af2 100644 (file)
@@ -1,11 +1,14 @@
 {
     "@metadata": {
         "authors": [
-            "Euriditi"
+            "Euriditi",
+            "Kushtrim",
+            "Elioqoshi"
         ]
     },
     "ooui-dialog-action-close": "Mbylle",
     "ooui-outline-control-move-down": "Zhvendose artikullin më poshtë",
     "ooui-outline-control-move-up": "Zhvendose artikullin më lart",
+    "ooui-outline-control-remove": "Hiq artikullin",
     "ooui-toolbar-more": "Më tepër..."
 }
\ No newline at end of file
index 74d654b..f7d6f04 100644 (file)
             "Per",
             "Sendelbach",
             "Skalman",
-            "WikiPhoenix"
+            "WikiPhoenix",
+            "Lokal Profil"
         ]
     },
     "ooui-dialog-action-close": "Stäng",
     "ooui-outline-control-move-down": "Flytta ned objekt",
     "ooui-outline-control-move-up": "Flytta upp objekt",
+    "ooui-outline-control-remove": "Ta bort objekt",
     "ooui-toolbar-more": "Mer"
 }
\ No newline at end of file
index 9a47ad7..42487c9 100644 (file)
@@ -20,5 +20,6 @@
     "ooui-dialog-action-close": "Закрити",
     "ooui-outline-control-move-down": "Перемістити елемент униз",
     "ooui-outline-control-move-up": "Перемістити елемент вгору",
+    "ooui-outline-control-remove": "Видалити елемент",
     "ooui-toolbar-more": "Більше"
 }
\ No newline at end of file
index b545ce6..342ad6f 100644 (file)
@@ -9,5 +9,6 @@
     "ooui-dialog-action-close": "Đóng",
     "ooui-outline-control-move-down": "Chuyển mục xuống",
     "ooui-outline-control-move-up": "Chuyển mục lên",
+    "ooui-outline-control-remove": "Xóa khoản",
     "ooui-toolbar-more": "Thêm"
 }
\ No newline at end of file
index aa36cd0..5cf353f 100644 (file)
Binary files a/resources/oojs-ui/images/icons/add-item.png and b/resources/oojs-ui/images/icons/add-item.png differ
index ff95399..2620e76 100644 (file)
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="iso-8859-1"?>
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24" height="24" viewBox="0, 0, 24, 24">
-  <g id="add-item">
-    <path d="M13,8 L11,8 L11,11 L8,11 L8,13 L11,13 L11,16 L13,16 L13,13 L16,13 L16,11 L13,11 z" fill="#000000"/>
-  </g>
-  <defs/>
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px"
+        height="24px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
+<g id="apply" style="opacity:0.75;">
+       <path d="M13,8 L11,8 L11,11 L8,11 L8,13 L11,13 L11,16 L13,16 L13,13 L16,13 L16,11 L13,11 z"/>
+</g>
 </svg>
index 468c78a..66a8072 100644 (file)
   box-shadow: none;
 }
 
+.oo-ui-bookletLayout > .oo-ui-gridLayout > .oo-ui-panelLayout {
+  -webkit-transition: width 250ms ease-in-out, height 250ms ease-in-out, top 250ms ease-in-out, left 250ms ease-in-out;
+     -moz-transition: width 250ms ease-in-out, height 250ms ease-in-out, top 250ms ease-in-out, left 250ms ease-in-out;
+      -ms-transition: width 250ms ease-in-out, height 250ms ease-in-out, top 250ms ease-in-out, left 250ms ease-in-out;
+       -o-transition: width 250ms ease-in-out, height 250ms ease-in-out, top 250ms ease-in-out, left 250ms ease-in-out;
+          transition: width 250ms ease-in-out, height 250ms ease-in-out, top 250ms ease-in-out, left 250ms ease-in-out;
+}
+
 .oo-ui-bookletLayout-outlinePanel {
   border-right: solid 1px #ddd;
 }
   background-color: #e1f3ff;
 }
 
+.oo-ui-menuSectionItemWidget {
+  color: #888;
+}
+
 .oo-ui-outlineControlsWidget {
   background-color: #fff;
 }
index 39406bb..1f13047 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (8ac38a5c31)
+ * OOjs UI v0.1.0-pre (efc7297353)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Tue Mar 04 2014 11:26:29 GMT-0800 (PST)
+ * Date: Fri Mar 07 2014 17:36:48 GMT-0800 (PST)
  */
 ( function () {
 
@@ -21,6 +21,28 @@ OO.ui = {};
 
 OO.ui.bind = $.proxy;
 
+/**
+ * @property {Object}
+ */
+OO.ui.Keys = {
+       'UNDEFINED': 0,
+       'BACKSPACE': 8,
+       'DELETE': 46,
+       'LEFT': 37,
+       'RIGHT': 39,
+       'UP': 38,
+       'DOWN': 40,
+       'ENTER': 13,
+       'END': 35,
+       'HOME': 36,
+       'TAB': 9,
+       'PAGEUP': 33,
+       'PAGEDOWN': 34,
+       'ESCAPE': 27,
+       'SHIFT': 16,
+       'SPACE': 32
+};
+
 /**
  * Get the user's language and any fallback languages.
  *
@@ -29,7 +51,7 @@ OO.ui.bind = $.proxy;
  * In environments that provide a localization system, this function should be overridden to
  * return the user's language(s). The default implementation returns English (en) only.
  *
- * @returns {string[]} Language codes, in descending order of priority
+ * @return {string[]} Language codes, in descending order of priority
  */
 OO.ui.getUserLanguages = function () {
        return [ 'en' ];
@@ -41,7 +63,7 @@ OO.ui.getUserLanguages = function () {
  * @param {Object.<string,Mixed>} obj Object keyed by language code
  * @param {string|null} [lang] Language code, if omitted or null defaults to any user language
  * @param {string} [fallback] Fallback code, used if no matching language can be found
- * @returns {Mixed} Local value
+ * @return {Mixed} Local value
  */
 OO.ui.getLocalValue = function ( obj, lang, fallback ) {
        var i, len, langs;
@@ -108,7 +130,7 @@ var messages = {
  * @abstract
  * @param {string} key Message key
  * @param {Mixed...} [params] Message parameters
- * @returns {string} Translated message with parameters substituted
+ * @return {string} Translated message with parameters substituted
  */
 OO.ui.msg = function ( key ) {
        var message = messages[key], params = Array.prototype.slice.call( arguments, 1 );
@@ -125,12 +147,14 @@ OO.ui.msg = function ( key ) {
        return message;
 };
 
+/** */
 OO.ui.deferMsg = function ( key ) {
        return function () {
                return OO.ui.msg( key );
        };
 };
 
+/** */
 OO.ui.resolveMsg = function ( msg ) {
        if ( $.isFunction( msg ) ) {
                return msg();
@@ -139,31 +163,11 @@ OO.ui.resolveMsg = function ( msg ) {
 };
 
 } )();
-
-// Add more as you need
-OO.ui.Keys = {
-       'UNDEFINED': 0,
-       'BACKSPACE': 8,
-       'DELETE': 46,
-       'LEFT': 37,
-       'RIGHT': 39,
-       'UP': 38,
-       'DOWN': 40,
-       'ENTER': 13,
-       'END': 35,
-       'HOME': 36,
-       'TAB': 9,
-       'PAGEUP': 33,
-       'PAGEDOWN': 34,
-       'ESCAPE': 27,
-       'SHIFT': 16,
-       'SPACE': 32
-};
 /**
  * DOM element abstraction.
  *
- * @class
  * @abstract
+ * @class
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -191,11 +195,6 @@ OO.ui.Element = function OoUiElement( config ) {
 
 /* Static Properties */
 
-/**
- * @static
- * @property
- * @inheritable
- */
 OO.ui.Element.static = {};
 
 /**
@@ -212,12 +211,12 @@ OO.ui.Element.static.tagName = 'div';
 /* Static Methods */
 
 /**
- * Gets a jQuery function within a specific document.
+ * Get a jQuery function within a specific document.
  *
  * @static
  * @param {jQuery|HTMLElement|HTMLDocument|Window} context Context to bind the function to
  * @param {OO.ui.Frame} [frame] Frame of the document context
- * @returns {Function} Bound jQuery function
+ * @return {Function} Bound jQuery function
  */
 OO.ui.Element.getJQuery = function ( context, frame ) {
        function wrapper( selector ) {
@@ -238,7 +237,7 @@ OO.ui.Element.getJQuery = function ( context, frame ) {
  *
  * @static
  * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Object to get the document for
- * @returns {HTMLDocument} Document object
+ * @return {HTMLDocument} Document object
  * @throws {Error} If context is invalid
  */
 OO.ui.Element.getDocument = function ( obj ) {
@@ -266,7 +265,7 @@ OO.ui.Element.getDocument = function ( obj ) {
  *
  * @static
  * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the window for
- * @returns {Window} Window object
+ * @return {Window} Window object
  */
 OO.ui.Element.getWindow = function ( obj ) {
        var doc = this.getDocument( obj );
@@ -278,7 +277,7 @@ OO.ui.Element.getWindow = function ( obj ) {
  *
  * @static
  * @param {jQuery|HTMLElement|HTMLDocument|Window} obj Context to get the direction for
- * @returns {string} Text direction, either `ltr` or `rtl`
+ * @return {string} Text direction, either `ltr` or `rtl`
  */
 OO.ui.Element.getDir = function ( obj ) {
        var isDoc, isWin;
@@ -306,7 +305,7 @@ OO.ui.Element.getDir = function ( obj ) {
  * @param {Window} from Window of the child frame
  * @param {Window} [to=window] Window of the parent frame
  * @param {Object} [offset] Offset to start with, used internally
- * @returns {Object} Offset object, containing left and top properties
+ * @return {Object} Offset object, containing left and top properties
  */
 OO.ui.Element.getFrameOffset = function ( from, to, offset ) {
        var i, len, frames, frame, rect;
@@ -348,7 +347,7 @@ OO.ui.Element.getFrameOffset = function ( from, to, offset ) {
  * @static
  * @param {jQuery} $from
  * @param {jQuery} $to
- * @returns {Object} Translated position coordinates, containing top and left properties
+ * @return {Object} Translated position coordinates, containing top and left properties
  */
 OO.ui.Element.getRelativePosition = function ( $from, $to ) {
        var from = $from.offset(),
@@ -465,7 +464,7 @@ OO.ui.Element.getClosestScrollableContainer = function ( el, dimension ) {
 };
 
 /**
- * Scroll element into view
+ * Scroll element into view.
  *
  * @static
  * @param {HTMLElement} el Element to scroll into view
@@ -528,7 +527,7 @@ OO.ui.Element.scrollIntoView = function ( el, config ) {
  *
  * Override this method to base the result on instance information.
  *
- * @returns {string} HTML tag name
+ * @return {string} HTML tag name
  */
 OO.ui.Element.prototype.getTagName = function () {
        return this.constructor.static.tagName;
@@ -537,7 +536,7 @@ OO.ui.Element.prototype.getTagName = function () {
 /**
  * Get the DOM document.
  *
- * @returns {HTMLDocument} Document object
+ * @return {HTMLDocument} Document object
  */
 OO.ui.Element.prototype.getElementDocument = function () {
        return OO.ui.Element.getDocument( this.$element );
@@ -546,7 +545,7 @@ OO.ui.Element.prototype.getElementDocument = function () {
 /**
  * Get the DOM window.
  *
- * @returns {Window} Window object
+ * @return {Window} Window object
  */
 OO.ui.Element.prototype.getElementWindow = function () {
        return OO.ui.Element.getWindow( this.$element );
@@ -555,7 +554,6 @@ OO.ui.Element.prototype.getElementWindow = function () {
 /**
  * Get closest scrollable container.
  *
- * @method
  * @see #static-method-getClosestScrollableContainer
  */
 OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
@@ -565,7 +563,7 @@ OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
 /**
  * Get group element is in.
  *
- * @returns {OO.ui.GroupElement|null} Group element, null if none
+ * @return {OO.ui.GroupElement|null} Group element, null if none
  */
 OO.ui.Element.prototype.getElementGroup = function () {
        return this.elementGroup;
@@ -583,9 +581,8 @@ OO.ui.Element.prototype.setElementGroup = function ( group ) {
 };
 
 /**
- * Scroll element into view
+ * Scroll element into view.
  *
- * @method
  * @see #static-method-scrollIntoView
  * @param {Object} [config={}]
  */
@@ -712,6 +709,10 @@ OO.mixinClass( OO.ui.Frame, OO.EventEmitter );
 
 /* Static Properties */
 
+/**
+ * @static
+ * @inheritdoc
+ */
 OO.ui.Frame.static.tagName = 'iframe';
 
 /* Events */
@@ -921,8 +922,8 @@ OO.ui.Frame.prototype.setSize = function ( width, height ) {
  * There are two ways to specify a title: set the static `title` property or provide a `title`
  * property in the configuration options. The latter will override the former.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Element
  * @mixins OO.EventEmitter
  *
@@ -1029,8 +1030,7 @@ OO.ui.Window.static.title = null;
 /**
  * Check if window is visible.
  *
- * @method
- * @returns {boolean} Window is visible
+ * @return {boolean} Window is visible
  */
 OO.ui.Window.prototype.isVisible = function () {
        return this.visible;
@@ -1039,8 +1039,7 @@ OO.ui.Window.prototype.isVisible = function () {
 /**
  * Check if window is opening.
  *
- * @method
- * @returns {boolean} Window is opening
+ * @return {boolean} Window is opening
  */
 OO.ui.Window.prototype.isOpening = function () {
        return this.opening;
@@ -1049,8 +1048,7 @@ OO.ui.Window.prototype.isOpening = function () {
 /**
  * Check if window is closing.
  *
- * @method
- * @returns {boolean} Window is closing
+ * @return {boolean} Window is closing
  */
 OO.ui.Window.prototype.isClosing = function () {
        return this.closing;
@@ -1059,8 +1057,7 @@ OO.ui.Window.prototype.isClosing = function () {
 /**
  * Get the window frame.
  *
- * @method
- * @returns {OO.ui.Frame} Frame of window
+ * @return {OO.ui.Frame} Frame of window
  */
 OO.ui.Window.prototype.getFrame = function () {
        return this.frame;
@@ -1069,7 +1066,7 @@ OO.ui.Window.prototype.getFrame = function () {
 /**
  * Get the title of the window.
  *
- * @returns {string} Title text
+ * @return {string} Title text
  */
 OO.ui.Window.prototype.getTitle = function () {
        return this.title;
@@ -1078,7 +1075,7 @@ OO.ui.Window.prototype.getTitle = function () {
 /**
  * Get the window icon.
  *
- * @returns {string} Symbolic name of icon
+ * @return {string} Symbolic name of icon
  */
 OO.ui.Window.prototype.getIcon = function () {
        return this.icon;
@@ -1137,7 +1134,7 @@ OO.ui.Window.prototype.setIcon = function ( icon ) {
 };
 
 /**
- * Set the position of window to fit with contents..
+ * Set the position of window to fit with contents.
  *
  * @param {string} left Left offset
  * @param {string} top Top offset
@@ -1190,7 +1187,6 @@ OO.ui.Window.prototype.fitWidthToContents = function ( min, max ) {
  *
  * Once this method is called, this.$$ can be used to create elements within the frame.
  *
- * @method
  * @fires initialize
  * @chainable
  */
@@ -1231,7 +1227,6 @@ OO.ui.Window.prototype.initialize = function () {
  *
  * When you override this method, you must call the parent method at the very beginning.
  *
- * @method
  * @abstract
  * @param {Object} [data] Window opening data
  */
@@ -1247,7 +1242,6 @@ OO.ui.Window.prototype.setup = function () {
  *
  * When you override this method, you must call the parent method at the very end.
  *
- * @method
  * @abstract
  * @param {Object} [data] Window closing data
  */
@@ -1260,7 +1254,6 @@ OO.ui.Window.prototype.teardown = function () {
  *
  * Do not override this method. See #setup for a way to make changes each time the window opens.
  *
- * @method
  * @param {Object} [data] Window opening data
  * @fires open
  * @chainable
@@ -1287,7 +1280,6 @@ OO.ui.Window.prototype.open = function ( data ) {
  *
  * See #teardown for a way to do something each time the window closes.
  *
- * @method
  * @param {Object} [data] Window closing data
  * @fires close
  * @chainable
@@ -1328,13 +1320,15 @@ OO.ui.WindowSet = function OoUiWindowSet( factory, config ) {
        this.factory = factory;
 
        /**
-        * List of all windows associated with this window set
+        * List of all windows associated with this window set.
+        *
         * @property {OO.ui.Window[]}
         */
        this.windowList = [];
 
        /**
         * Mapping of OO.ui.Window objects created by name from the #factory.
+        *
         * @property {Object}
         */
        this.windows = {};
@@ -1381,7 +1375,6 @@ OO.mixinClass( OO.ui.WindowSet, OO.EventEmitter );
 /**
  * Handle a window that's being opened.
  *
- * @method
  * @param {OO.ui.Window} win Window that's being opened
  * @param {Object} [config] Window opening information
  * @fires opening
@@ -1397,7 +1390,6 @@ OO.ui.WindowSet.prototype.onWindowOpening = function ( win, config ) {
 /**
  * Handle a window that's been opened.
  *
- * @method
  * @param {OO.ui.Window} win Window that's been opened
  * @param {Object} [config] Window opening information
  * @fires open
@@ -1409,7 +1401,6 @@ OO.ui.WindowSet.prototype.onWindowOpen = function ( win, config ) {
 /**
  * Handle a window that's being closed.
  *
- * @method
  * @param {OO.ui.Window} win Window that's being closed
  * @param {Object} [config] Window closing information
  * @fires closing
@@ -1422,7 +1413,6 @@ OO.ui.WindowSet.prototype.onWindowClosing = function ( win, config ) {
 /**
  * Handle a window that's been closed.
  *
- * @method
  * @param {OO.ui.Window} win Window that's been closed
  * @param {Object} [config] Window closing information
  * @fires close
@@ -1434,8 +1424,7 @@ OO.ui.WindowSet.prototype.onWindowClose = function ( win, config ) {
 /**
  * Get the current window.
  *
- * @method
- * @returns {OO.ui.Window} Current window
+ * @return {OO.ui.Window} Current window
  */
 OO.ui.WindowSet.prototype.getCurrentWindow = function () {
        return this.currentWindow;
@@ -1454,12 +1443,22 @@ OO.ui.WindowSet.prototype.getWindow = function ( name ) {
                throw new Error( 'Unknown window: ' + name );
        }
        if ( !( name in this.windows ) ) {
-               win = this.windows[name] = this.factory.create( name, this, { '$': this.$ } );
+               win = this.windows[name] = this.createWindow( name );
                this.addWindow( win );
        }
        return this.windows[name];
 };
 
+/**
+ * Create a window for use in this window set.
+ *
+ * @param {string} name Symbolic name of window
+ * @return {OO.ui.Window} Window with specified name
+ */
+OO.ui.WindowSet.prototype.createWindow = function ( name ) {
+       return this.factory.create( name, { '$': this.$ } );
+};
+
 /**
  * Add a given window to this window set.
  *
@@ -1484,20 +1483,18 @@ OO.ui.WindowSet.prototype.addWindow = function ( win ) {
        this.$element.append( win.$element );
 };
 /**
- * Modal dialog box.
- *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Window
  *
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {boolean} [footless] Hide foot
- * @cfg {boolean} [small] Make the dialog small
+ * @cfg {string} [size='large'] Symbolic name of dialog size, `small`, `medium` or `large`
  */
 OO.ui.Dialog = function OoUiDialog( config ) {
        // Configuration initialization
-       config = config || {};
+       config = $.extend( { 'size': 'large' }, config );
 
        // Parent constructor
        OO.ui.Window.call( this, config );
@@ -1505,7 +1502,7 @@ OO.ui.Dialog = function OoUiDialog( config ) {
        // Properties
        this.visible = false;
        this.footless = !!config.footless;
-       this.small = !!config.small;
+       this.size = null;
        this.onWindowMouseWheelHandler = OO.ui.bind( this.onWindowMouseWheel, this );
        this.onDocumentKeyDownHandler = OO.ui.bind( this.onDocumentKeyDown, this );
 
@@ -1515,6 +1512,7 @@ OO.ui.Dialog = function OoUiDialog( config ) {
 
        // Initialization
        this.$element.addClass( 'oo-ui-dialog' );
+       this.setSize( config.size );
 };
 
 /* Inheritance */
@@ -1533,12 +1531,23 @@ OO.inheritClass( OO.ui.Dialog, OO.ui.Window );
  */
 OO.ui.Dialog.static.name = '';
 
+/**
+ * Map of symbolic size names and CSS classes.
+ *
+ * @static
+ * @property {Object}
+ * @inheritable
+ */
+OO.ui.Dialog.static.sizeCssClasses = {
+       'small': 'oo-ui-dialog-small',
+       'medium': 'oo-ui-dialog-medium',
+       'large': 'oo-ui-dialog-large'
+};
+
 /* Methods */
 
 /**
  * Handle close button click events.
- *
- * @method
  */
 OO.ui.Dialog.prototype.onCloseButtonClick = function () {
        this.close( { 'action': 'cancel' } );
@@ -1547,7 +1556,6 @@ OO.ui.Dialog.prototype.onCloseButtonClick = function () {
 /**
  * Handle window mouse wheel events.
  *
- * @method
  * @param {jQuery.Event} e Mouse wheel event
  */
 OO.ui.Dialog.prototype.onWindowMouseWheel = function () {
@@ -1557,7 +1565,6 @@ OO.ui.Dialog.prototype.onWindowMouseWheel = function () {
 /**
  * Handle document key down events.
  *
- * @method
  * @param {jQuery.Event} e Key down event
  */
 OO.ui.Dialog.prototype.onDocumentKeyDown = function ( e ) {
@@ -1578,7 +1585,6 @@ OO.ui.Dialog.prototype.onDocumentKeyDown = function ( e ) {
 /**
  * Handle frame document key down events.
  *
- * @method
  * @param {jQuery.Event} e Key down event
  */
 OO.ui.Dialog.prototype.onFrameDocumentKeyDown = function ( e ) {
@@ -1593,6 +1599,29 @@ OO.ui.Dialog.prototype.onOpening = function () {
        this.$element.addClass( 'oo-ui-dialog-open' );
 };
 
+/**
+ * Set dialog size.
+ *
+ * @param {string} [size='large'] Symbolic name of dialog size, `small`, `medium` or `large`
+ */
+OO.ui.Dialog.prototype.setSize = function ( size ) {
+       var name, state, cssClass,
+               sizeCssClasses = OO.ui.Dialog.static.sizeCssClasses;
+
+       if ( !sizeCssClasses[size] ) {
+               size = 'large';
+       }
+       this.size = size;
+       for ( name in sizeCssClasses ) {
+               state = name === size;
+               cssClass = sizeCssClasses[name];
+               this.$element.toggleClass( cssClass, state );
+               if ( this.frame.$content ) {
+                       this.frame.$content.toggleClass( cssClass, state );
+               }
+       }
+};
+
 /**
  * @inheritdoc
  */
@@ -1617,9 +1646,6 @@ OO.ui.Dialog.prototype.initialize = function () {
        if ( this.footless ) {
                this.frame.$content.addClass( 'oo-ui-dialog-content-footless' );
        }
-       if ( this.small ) {
-               this.$frame.addClass( 'oo-ui-window-frame-small' );
-       }
        this.closeButton.$element.addClass( 'oo-ui-window-closeButton' );
        this.$head.append( this.closeButton.$element );
 };
@@ -1666,8 +1692,8 @@ OO.ui.Dialog.prototype.close = function ( data ) {
 /**
  * Container for elements.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Element
  * @mixins OO.EventEmitter
  *
@@ -1696,8 +1722,8 @@ OO.mixinClass( OO.ui.Layout, OO.EventEmitter );
 /**
  * User interface control.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Element
  * @mixins OO.EventEmitter
  *
@@ -1742,7 +1768,6 @@ OO.mixinClass( OO.ui.Widget, OO.EventEmitter );
 /**
  * Check if the widget is disabled.
  *
- * @method
  * @param {boolean} Button is disabled
  */
 OO.ui.Widget.prototype.isDisabled = function () {
@@ -1752,7 +1777,6 @@ OO.ui.Widget.prototype.isDisabled = function () {
 /**
  * Update the disabled state, in case of changes in parent widget.
  *
- * @method
  * @chainable
  */
 OO.ui.Widget.prototype.updateDisabled = function () {
@@ -1765,7 +1789,6 @@ OO.ui.Widget.prototype.updateDisabled = function () {
  *
  * This should probably change the widgets's appearance and prevent it from being used.
  *
- * @method
  * @param {boolean} disabled Disable widget
  * @chainable
  */
@@ -2647,8 +2670,8 @@ OO.ui.TitledElement.prototype.getTitle = function () {
 /**
  * Generic toolbar tool.
  *
- * @class
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.IconedElement
  *
@@ -2707,6 +2730,10 @@ OO.mixinClass( OO.ui.Tool, OO.ui.IconedElement );
 
 /* Static Properties */
 
+/**
+ * @static
+ * @inheritdoc
+ */
 OO.ui.Tool.static.tagName = 'span';
 
 /**
@@ -2756,11 +2783,11 @@ OO.ui.Tool.static.autoAdd = true;
 /**
  * Check if this tool is compatible with given data.
  *
- * @method
  * @static
+ * @method
  * @inheritable
  * @param {Mixed} data Data to check
- * @returns {boolean} Tool can be used with data
+ * @return {boolean} Tool can be used with data
  */
 OO.ui.Tool.static.isCompatibleWith = function () {
        return false;
@@ -2774,7 +2801,6 @@ OO.ui.Tool.static.isCompatibleWith = function () {
  * This is an abstract method that must be overridden in a concrete subclass.
  *
  * @abstract
- * @method
  */
 OO.ui.Tool.prototype.onUpdateState = function () {
        throw new Error(
@@ -2788,7 +2814,6 @@ OO.ui.Tool.prototype.onUpdateState = function () {
  * This is an abstract method that must be overridden in a concrete subclass.
  *
  * @abstract
- * @method
  */
 OO.ui.Tool.prototype.onSelect = function () {
        throw new Error(
@@ -2799,7 +2824,6 @@ OO.ui.Tool.prototype.onSelect = function () {
 /**
  * Check if the button is active.
  *
- * @method
  * @param {boolean} Button is active
  */
 OO.ui.Tool.prototype.isActive = function () {
@@ -2809,7 +2833,6 @@ OO.ui.Tool.prototype.isActive = function () {
 /**
  * Make the button appear active or inactive.
  *
- * @method
  * @param {boolean} state Make button appear active
  */
 OO.ui.Tool.prototype.setActive = function ( state ) {
@@ -2824,7 +2847,6 @@ OO.ui.Tool.prototype.setActive = function ( state ) {
 /**
  * Get the tool title.
  *
- * @method
  * @param {string|Function} title Title text or a function that returns text
  * @chainable
  */
@@ -2837,8 +2859,7 @@ OO.ui.Tool.prototype.setTitle = function ( title ) {
 /**
  * Get the tool title.
  *
- * @method
- * @returns {string} Title text
+ * @return {string} Title text
  */
 OO.ui.Tool.prototype.getTitle = function () {
        return this.title;
@@ -2847,8 +2868,7 @@ OO.ui.Tool.prototype.getTitle = function () {
 /**
  * Get the tool's symbolic name.
  *
- * @method
- * @returns {string} Symbolic name of tool
+ * @return {string} Symbolic name of tool
  */
 OO.ui.Tool.prototype.getName = function () {
        return this.constructor.static.name;
@@ -2856,8 +2876,6 @@ OO.ui.Tool.prototype.getName = function () {
 
 /**
  * Update the title.
- *
- * @method
  */
 OO.ui.Tool.prototype.updateTitle = function () {
        var titleTooltips = this.toolGroup.constructor.static.titleTooltips,
@@ -2888,8 +2906,6 @@ OO.ui.Tool.prototype.updateTitle = function () {
 
 /**
  * Destroy tool.
- *
- * @method
  */
 OO.ui.Tool.prototype.destroy = function () {
        this.toolbar.disconnect( this );
@@ -2959,8 +2975,7 @@ OO.mixinClass( OO.ui.Toolbar, OO.ui.GroupElement );
 /**
  * Get the tool factory.
  *
- * @method
- * @returns {OO.Factory} Tool factory
+ * @return {OO.Factory} Tool factory
  */
 OO.ui.Toolbar.prototype.getToolFactory = function () {
        return this.toolFactory;
@@ -2969,7 +2984,6 @@ OO.ui.Toolbar.prototype.getToolFactory = function () {
 /**
  * Handles mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.Toolbar.prototype.onMouseDown = function ( e ) {
@@ -2992,11 +3006,11 @@ OO.ui.Toolbar.prototype.initialize = function () {
  * Setup toolbar.
  *
  * Tools can be specified in the following ways:
- *  - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- *  - All tools in a group: `{ 'group': 'group-name' }`
- *  - All tools: `'*'` - Using this will make the group a list with a "More" label by default
  *
- * @method
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'` - Using this will make the group a list with a "More" label by default
+ *
  * @param {Object.<string,Array>} groups List of tool group configurations
  * @param {Array|string} [groups.include] Tools to include
  * @param {Array|string} [groups.exclude] Tools to exclude
@@ -3095,7 +3109,7 @@ OO.ui.Toolbar.prototype.releaseTool = function ( tool ) {
  * This is a stub that should be overridden to provide access to accelerator information.
  *
  * @param {string} name Symbolic name of tool
- * @returns {string|undefined} Tool accelerator label if available
+ * @return {string|undefined} Tool accelerator label if available
  */
 OO.ui.Toolbar.prototype.getToolAccelerator = function () {
        return undefined;
@@ -3118,6 +3132,7 @@ OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
 
 /* Methods */
 
+/** */
 OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
        var i, len, included, promoted, demoted,
                auto = [],
@@ -3144,14 +3159,15 @@ OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, dem
  * Get a flat list of names from a list of names or groups.
  *
  * Tools can be specified in the following ways:
- *  - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- *  - All tools in a group: `{ 'group': 'group-name' }`
- *  - All tools: `'*'`
+ *
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'`
  *
  * @private
  * @param {Array|string} collection List of tools
  * @param {Object} [used] Object with names that should be skipped as properties; extracted
- *   names will be added as properties
+ *  names will be added as properties
  * @return {string[]} List of extracted names
  */
 OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
@@ -3214,16 +3230,17 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
 /**
  * Collection of tools.
  *
- * @class
+ * Tools can be specified in the following ways:
+ *
+ * - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
+ * - All tools in a group: `{ 'group': 'group-name' }`
+ * - All tools: `'*'`
+ *
  * @abstract
+ * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.GroupElement
  *
- * Tools can be specified in the following ways:
- *  - A specific tool: `{ 'name': 'tool-name' }` or `'tool-name'`
- *  - All tools in a group: `{ 'group': 'group-name' }`
- *  - All tools: `'*'`
- *
  * @constructor
  * @param {OO.ui.Toolbar} toolbar
  * @param {Object} [config] Configuration options
@@ -3306,7 +3323,6 @@ OO.ui.ToolGroup.static.accelTooltips = false;
 /**
  * Handle mouse down events.
  *
- * @method
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.ToolGroup.prototype.onMouseDown = function ( e ) {
@@ -3325,7 +3341,6 @@ OO.ui.ToolGroup.prototype.onMouseDown = function ( e ) {
 /**
  * Handle captured mouse up events.
  *
- * @method
  * @param {Event} e Mouse up event
  */
 OO.ui.ToolGroup.prototype.onCapturedMouseUp = function ( e ) {
@@ -3338,7 +3353,6 @@ OO.ui.ToolGroup.prototype.onCapturedMouseUp = function ( e ) {
 /**
  * Handle mouse up events.
  *
- * @method
  * @param {jQuery.Event} e Mouse up event
  */
 OO.ui.ToolGroup.prototype.onMouseUp = function ( e ) {
@@ -3355,7 +3369,6 @@ OO.ui.ToolGroup.prototype.onMouseUp = function ( e ) {
 /**
  * Handle mouse over events.
  *
- * @method
  * @param {jQuery.Event} e Mouse over event
  */
 OO.ui.ToolGroup.prototype.onMouseOver = function ( e ) {
@@ -3369,7 +3382,6 @@ OO.ui.ToolGroup.prototype.onMouseOver = function ( e ) {
 /**
  * Handle mouse out events.
  *
- * @method
  * @param {jQuery.Event} e Mouse out event
  */
 OO.ui.ToolGroup.prototype.onMouseOut = function ( e ) {
@@ -3386,10 +3398,9 @@ OO.ui.ToolGroup.prototype.onMouseOut = function ( e ) {
  * Only tool links are considered, which prevents other elements in the tool such as popups from
  * triggering tool group interactions.
  *
- * @method
  * @private
  * @param {jQuery.Event} e
- * @returns {OO.ui.Tool|null} Tool, `null` if none was found
+ * @return {OO.ui.Tool|null} Tool, `null` if none was found
  */
 OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
        var tool,
@@ -3406,6 +3417,7 @@ OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
  * Handle tool registry register events.
  *
  * If a tool is registered after the group is created, we must repopulate the list to account for:
+ *
  * - a tool being added that may be included
  * - a tool already included being overridden
  *
@@ -3426,8 +3438,6 @@ OO.ui.ToolGroup.prototype.getToolbar = function () {
 
 /**
  * Add and remove tools based on configuration.
- *
- * @method
  */
 OO.ui.ToolGroup.prototype.populate = function () {
        var i, len, name, tool,
@@ -3483,8 +3493,6 @@ OO.ui.ToolGroup.prototype.populate = function () {
 
 /**
  * Destroy tool group.
- *
- * @method
  */
 OO.ui.ToolGroup.prototype.destroy = function () {
        var name;
@@ -3842,6 +3850,7 @@ OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
        this.ignoreFocus = false;
        this.stackLayout = new OO.ui.StackLayout( { '$': this.$, 'continuous': !!config.continuous } );
        this.autoFocus = !!config.autoFocus;
+       this.outlineVisible = false;
        this.outlined = !!config.outlined;
        if ( this.outlined ) {
                this.editable = !!config.editable;
@@ -3852,6 +3861,7 @@ OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
                this.gridLayout = new OO.ui.GridLayout(
                        [this.outlinePanel, this.stackLayout], { '$': this.$, 'widths': [1, 2] }
                );
+               this.outlineVisible = true;
                if ( this.editable ) {
                        this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
                                this.outlineWidget,
@@ -3986,6 +3996,32 @@ OO.ui.BookletLayout.prototype.isEditable = function () {
        return this.editable;
 };
 
+/**
+ * Check if booklet has editing controls.
+ *
+ * @method
+ * @returns {boolean} Booklet is outlined
+ */
+OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
+       return this.outlined && this.outlineVisible;
+};
+
+/**
+ * Hide or show the outline.
+ *
+ * @param {boolean} [show] Show outline, omit to invert current state
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
+       if ( this.outlined ) {
+               show = show === undefined ? !this.outlineVisible : !!show;
+               this.outlineVisible = show;
+               this.gridLayout.layout( show ? [ 1, 2 ] : [ 0, 1 ], [ 1 ] );
+       }
+
+       return this;
+};
+
 /**
  * Get the outline widget.
  *
@@ -4876,6 +4912,78 @@ OO.ui.ItemWidget.prototype.setElementGroup = function ( group ) {
 
        return this;
 };
+/**
+ * Creates an OO.ui.IconWidget object.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.IconedElement
+ * @mixins OO.ui.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IconWidget = function OoUiIconWidget( config ) {
+       // Config intialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Widget.call( this, config );
+
+       // Mixin constructors
+       OO.ui.IconedElement.call( this, this.$element, config );
+       OO.ui.TitledElement.call( this, this.$element, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-iconWidget' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.IconWidget, OO.ui.Widget );
+
+OO.mixinClass( OO.ui.IconWidget, OO.ui.IconedElement );
+OO.mixinClass( OO.ui.IconWidget, OO.ui.TitledElement );
+
+/* Static Properties */
+
+OO.ui.IconWidget.static.tagName = 'span';
+/**
+ * Creates an OO.ui.IndicatorWidget object.
+ *
+ * @class
+ * @extends OO.ui.Widget
+ * @mixins OO.ui.IndicatedElement
+ * @mixins OO.ui.TitledElement
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.IndicatorWidget = function OoUiIndicatorWidget( config ) {
+       // Config intialization
+       config = config || {};
+
+       // Parent constructor
+       OO.ui.Widget.call( this, config );
+
+       // Mixin constructors
+       OO.ui.IndicatedElement.call( this, this.$element, config );
+       OO.ui.TitledElement.call( this, this.$element, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-indicatorWidget' );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.IndicatorWidget, OO.ui.Widget );
+
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.IndicatedElement );
+OO.mixinClass( OO.ui.IndicatorWidget, OO.ui.TitledElement );
+
+/* Static Properties */
+
+OO.ui.IndicatorWidget.static.tagName = 'span';
 /**
  * Container for multiple related buttons.
  *
@@ -6836,7 +6944,7 @@ OO.ui.OutlineItemWidget.prototype.setLevel = function ( level ) {
        return this;
 };
 /**
- * Create an OO.ui.ButtonSelect object.
+ * Create an OO.ui.ButtonOptionWidget object.
  *
  * @class
  * @extends OO.ui.OptionWidget
index 5609496..daf6f35 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (8ac38a5c31)
+ * OOjs UI v0.1.0-pre (efc7297353)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Tue Mar 04 2014 11:26:29 GMT-0800 (PST)
+ * Date: Fri Mar 07 2014 17:36:48 GMT-0800 (PST)
  */
 
 /* Textures */
   left: 0;
   padding: 1em;
   line-height: 1em;
+  /* Fix for strange opacity-related rendering issues.
+          CAUTION: -webkit-backface-visibility: hidden; is EXTREMELY DANGEROUS.
+          If applied to a VE surface directly, it will break selection of
+          FocusableNodes, and in the past it's caused transparent PNGs to
+          render as opaque black images. For some reason applying it to the dialog
+          wrapper in the main document fixes opacity-related behavior in the iframe
+          document, but doesn't break the surface inside the iframe. */
+
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
 }
 
 .oo-ui-dialog .oo-ui-window-frame {
   right: 0;
   bottom: 1em;
   left: 0;
-  width: 800px;
-  max-height: 600px;
   min-height: 12em;
   margin: auto;
   overflow: hidden;
 }
 
-.oo-ui-dialog .oo-ui-window-frame-small {
-  max-width: 600px;
+.oo-ui-dialog-small .oo-ui-window-frame {
+  width: 400px;
+  max-height: 200px;
+}
+
+.oo-ui-dialog-medium .oo-ui-window-frame {
+  width: 600px;
   max-height: 400px;
 }
 
+.oo-ui-dialog-large .oo-ui-window-frame {
+  width: 800px;
+  max-height: 600px;
+}
+
 .oo-ui-dialog .oo-ui-frame {
   width: 100%;
   height: 100%;
 }
 
 .oo-ui-buttonedElement-framed.oo-ui-iconedElement.oo-ui-labeledElement .oo-ui-buttonedElement-button > .oo-ui-iconedElement-icon {
-  margin-right: 0;
+  margin-right: 0.3em;
   margin-left: -0.5em;
 }
 
   z-index: 4;
 }
 
+.oo-ui-iconWidget {
+  display: inline-block;
+  width: 1.9em;
+  height: 1.9em;
+  line-height: 2.5em;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  opacity: 0.8;
+}
+
+.oo-ui-iconWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+
+.oo-ui-indicatorWidget {
+  display: inline-block;
+  width: 1.9em;
+  height: 1.9em;
+  line-height: 2.5em;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  opacity: 0.8;
+}
+
+.oo-ui-indicatorWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+
 .oo-ui-selectWidget {
   padding: 0;
   margin: 0;
   display: block;
 }
 
+.oo-ui-menuSectionItemWidget {
+  padding: 0.33em 0.75em;
+  cursor: default;
+}
+
 .oo-ui-outlineControlsWidget {
   height: 3em;
 }
index 70cb221..f924e9b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs v1.0.7-pre (9c04f3e917)
+ * OOjs v1.0.7-pre (22e610a5e9)
  * https://www.mediawiki.org/wiki/OOjs
  *
  * Copyright 2011-2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Fri Feb 14 2014 17:51:43 GMT-0800 (PST)
+ * Date: Fri Mar 07 2014 17:36:23 GMT-0800 (PST)
  */
 ( function ( global ) {
 
@@ -26,7 +26,6 @@ var
 /**
  * Assert whether a value is a plain object or not.
  *
- * @method
  * @param {Mixed} obj
  * @return {boolean}
  */
@@ -61,20 +60,20 @@ oo.isPlainObject = function ( obj ) {
  *  This is how prototypal inheritance works, it can only be one straight chain
  *  (just like classical inheritance in PHP for example). If you need to work with
  *  multiple constructors consider storing an instance of the other constructor in a
- *  property instead, or perhaps use a mixin (see oo.mixinClass).
+ *  property instead, or perhaps use a mixin (see OO.mixinClass).
  *
  *     function Thing() {}
  *     Thing.prototype.exists = function () {};
  *
  *     function Person() {
- *         this.constructor.super.apply( this, arguments );
+ *         Person.super.apply( this, arguments );
  *     }
- *     oo.inheritClass( Person, Thing );
+ *     OO.inheritClass( Person, Thing );
  *     Person.static.defaultEyeCount = 2;
  *     Person.prototype.walk = function () {};
  *
  *     function Jumper() {
- *         this.constructor.super.apply( this, arguments );
+ *         Jumper.super.apply( this, arguments );
  *     }
  *     OO.inheritClass( Jumper, Person );
  *     Jumper.prototype.jump = function () {};
@@ -85,7 +84,6 @@ oo.isPlainObject = function ( obj ) {
  *     x.walk();
  *     x instanceof Thing && x instanceof Person && x instanceof Jumper;
  *
- * @method
  * @param {Function} targetFn
  * @param {Function} originFn
  * @throws {Error} If target already inherits from origin
@@ -139,7 +137,6 @@ oo.inheritClass = function ( targetFn, originFn ) {
  *     OO.inheritClass( FooBar, Foo );
  *     OO.mixinClass( FooBar, ContextLazyLoad );
  *
- * @method
  * @param {Function} targetFn
  * @param {Function} originFn
  */
@@ -187,7 +184,6 @@ oo.mixinClass = function ( targetFn, originFn ) {
  *     foo2.getAge(); // 21
  *     foo.getAge(); // 22
  *
- * @method
  * @param {Object} origin
  * @return {Object} Clone of origin
  */
@@ -206,11 +202,10 @@ oo.cloneObject = function ( origin ) {
 };
 
 /**
- * Gets an array of all property values in an object.
+ * Get an array of all property values in an object.
  *
- * @method
  * @param {Object} Object to get values from
- * @returns {Array} List of object values
+ * @return {Array} List of object values
  */
 oo.getObjectValues = function ( obj ) {
        var key, values;
@@ -236,11 +231,10 @@ oo.getObjectValues = function ( obj ) {
  * the other. An asymmetrical test may also be performed, which checks only that properties in the
  * first object are present in the second object, but not the inverse.
  *
- * @method
  * @param {Object} a First object to compare
  * @param {Object} b Second object to compare
  * @param {boolean} [asymmetrical] Whether to check only that b contains values from a
- * @returns {boolean} If the objects contain the same values as each other
+ * @return {boolean} If the objects contain the same values as each other
  */
 oo.compare = function ( a, b, asymmetrical ) {
        var aValue, bValue, aType, bType, k;
@@ -269,10 +263,9 @@ oo.compare = function ( a, b, asymmetrical ) {
  *
  * Copies are deep, and will either be an object or an array depending on `source`.
  *
- * @method
  * @param {Object} source Object to copy
  * @param {Function} [callback] Applied to leaf values before they added to the clone
- * @returns {Object} Copy of source object
+ * @return {Object} Copy of source object
  */
 oo.copy = function ( source, callback ) {
        var key, sourceValue, sourceType, destination;
@@ -310,8 +303,9 @@ oo.copy = function ( source, callback ) {
 };
 
 /**
- * Generates a hash of an object based on its name and data.
- * Performance optimization: http://jsperf.com/ve-gethash-201208#/toJson_fnReplacerIfAoForElse
+ * Generate a hash of an object based on its name and data.
+ *
+ * Performance optimization: <http://jsperf.com/ve-gethash-201208#/toJson_fnReplacerIfAoForElse>
  *
  * To avoid two objects with the same values generating different hashes, we utilize the replacer
  * argument of JSON.stringify and sort the object by key as it's being serialized. This may or may
@@ -322,20 +316,21 @@ oo.copy = function ( source, callback ) {
  * ourselves. This allows classes to define custom hashing.
  *
  * @param {Object} val Object to generate hash for
- * @returns {string} Hash of object
+ * @return {string} Hash of object
  */
 oo.getHash = function ( val ) {
        return JSON.stringify( val, oo.getHash.keySortReplacer );
 };
 
 /**
- * Helper function for oo.getHash which sorts objects by key.
+ * Helper function for OO.getHash which sorts objects by key.
  *
  * This is a callback passed into JSON.stringify.
  *
+ * @method getHash_keySortReplacer
  * @param {string} key Property name of value being replaced
  * @param {Mixed} val Property value to replace
- * @returns {Mixed} Replacement value
+ * @return {Mixed} Replacement value
  */
 oo.getHash.keySortReplacer = function ( key, val ) {
        var normalized, keys, i, len;
@@ -365,13 +360,13 @@ oo.getHash.keySortReplacer = function ( key, val ) {
 /**
  * Compute the union (duplicate-free merge) of a set of arrays.
  *
- * Arrays values must be convertable to object keys (strings)
+ * Arrays values must be convertable to object keys (strings).
  *
  * By building an object (with the values for keys) in parallel with
- * the array, a new item's existence in the union can be computed faster
+ * the array, a new item's existence in the union can be computed faster.
  *
  * @param {Array...} arrays Arrays to union
- * @returns {Array} Union of the arrays
+ * @return {Array} Union of the arrays
  */
 oo.simpleArrayUnion = function () {
        var i, ilen, arr, j, jlen,
@@ -396,16 +391,16 @@ oo.simpleArrayUnion = function () {
  *
  * An intersection checks the item exists in 'b' while difference checks it doesn't.
  *
- * Arrays values must be convertable to object keys (strings)
+ * Arrays values must be convertable to object keys (strings).
  *
  * By building an object (with the values for keys) of 'b' we can
- * compute the result faster
+ * compute the result faster.
  *
  * @private
  * @param {Array} a First array
  * @param {Array} b Second array
  * @param {boolean} includeB Whether to items in 'b'
- * @returns {Array} Combination (intersection or difference) of arrays
+ * @return {Array} Combination (intersection or difference) of arrays
  */
 function simpleArrayCombine( a, b, includeB ) {
        var i, ilen, isInB,
@@ -429,11 +424,11 @@ function simpleArrayCombine( a, b, includeB ) {
 /**
  * Compute the intersection of two arrays (items in both arrays).
  *
- * Arrays values must be convertable to object keys (strings)
+ * Arrays values must be convertable to object keys (strings).
  *
  * @param {Array} a First array
  * @param {Array} b Second array
- * @returns {Array} Intersection of arrays
+ * @return {Array} Intersection of arrays
  */
 oo.simpleArrayIntersection = function ( a, b ) {
        return simpleArrayCombine( a, b, true );
@@ -442,25 +437,28 @@ oo.simpleArrayIntersection = function ( a, b ) {
 /**
  * Compute the difference of two arrays (items in 'a' but not 'b').
  *
- * Arrays values must be convertable to object keys (strings)
+ * Arrays values must be convertable to object keys (strings).
  *
  * @param {Array} a First array
  * @param {Array} b Second array
- * @returns {Array} Intersection of arrays
+ * @return {Array} Intersection of arrays
  */
 oo.simpleArrayDifference = function ( a, b ) {
        return simpleArrayCombine( a, b, false );
 };
 /**
- * Event emitter.
- *
  * @class OO.EventEmitter
  *
  * @constructor
- * @property {Object} bindings
  */
 oo.EventEmitter = function OoEventEmitter() {
        // Properties
+
+       /**
+        * Storage of bound event handlers by event name.
+        *
+        * @property
+        */
        this.bindings = {};
 };
 
@@ -471,7 +469,6 @@ oo.EventEmitter = function OoEventEmitter() {
  *
  * If the callback/context are already bound to the event, they will not be bound again.
  *
- * @method
  * @param {string} event Type of event to listen to
  * @param {Function} callback Function to call when event occurs
  * @param {Array} [args] Arguments to pass to listener, will be prepended to emitted arguments
@@ -516,7 +513,6 @@ oo.EventEmitter.prototype.on = function ( event, callback, args, context ) {
 /**
  * Adds a one-time listener to a specific event.
  *
- * @method
  * @param {string} event Type of event to listen to
  * @param {Function} listener Listener to call when event occurs
  * @chainable
@@ -532,7 +528,6 @@ oo.EventEmitter.prototype.once = function ( event, listener ) {
 /**
  * Remove a specific listener from a specific event.
  *
- * @method
  * @param {string} event Type of event to remove listener from
  * @param {Function} [callback] Listener to remove, omit to remove all
  * @param {Object} [context=null] Object used context for callback function or method
@@ -577,13 +572,13 @@ oo.EventEmitter.prototype.off = function ( event, callback, context ) {
 
 /**
  * Emit an event.
+ *
  * TODO: Should this be chainable? What is the usefulness of the boolean
  * return value here?
  *
- * @method
  * @param {string} event Type of event
  * @param {Mixed} args First in a list of variadic arguments passed to event handler (optional)
- * @returns {boolean} If event was handled by at least one listener
+ * @return {boolean} If event was handled by at least one listener
  */
 oo.EventEmitter.prototype.emit = function ( event ) {
        var i, len, binding, bindings, args;
@@ -607,12 +602,11 @@ oo.EventEmitter.prototype.emit = function ( event ) {
 /**
  * Connect event handlers to an object.
  *
- * @method
  * @param {Object} context Object to call methods on when events occur
  * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} methods List of
- * event bindings keyed by event name containing either method names, functions or arrays containing
- * method name or function followed by a list of arguments to be passed to callback before emitted
- * arguments
+ *  event bindings keyed by event name containing either method names, functions or arrays containing
+ *  method name or function followed by a list of arguments to be passed to callback before emitted
+ *  arguments
  * @chainable
  */
 oo.EventEmitter.prototype.connect = function ( context, methods ) {
@@ -647,7 +641,6 @@ oo.EventEmitter.prototype.connect = function ( context, methods ) {
 /**
  * Disconnect event handlers from an object.
  *
- * @method
  * @param {Object} context Object to disconnect methods from
  * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} [methods] List of
  * event bindings keyed by event name containing either method names or functions
@@ -688,8 +681,6 @@ oo.EventEmitter.prototype.disconnect = function ( context, methods ) {
        return this;
 };
 /**
- * Data registry.
- *
  * @class OO.Registry
  * @mixins OO.EventEmitter
  *
@@ -722,52 +713,44 @@ oo.mixinClass( oo.Registry, oo.EventEmitter );
  *
  * Only the base name will be registered, overriding any existing entry with the same base name.
  *
- * @method
  * @param {string|string[]} name Symbolic name or list of symbolic names
  * @param {Mixed} data Data to associate with symbolic name
  * @fires register
  * @throws {Error} Name argument must be a string or array
  */
 oo.Registry.prototype.register = function ( name, data ) {
-       if ( typeof name !== 'string' && !Array.isArray( name ) ) {
-               throw new Error( 'Name argument must be a string or array, cannot be a ' + typeof name );
-       }
        var i, len;
-       if ( Array.isArray( name ) ) {
+       if ( typeof name === 'string' ) {
+               this.registry[name] = data;
+               this.emit( 'register', name, data );
+       } else if ( Array.isArray( name ) ) {
                for ( i = 0, len = name.length; i < len; i++ ) {
                        this.register( name[i], data );
                }
-       } else if ( typeof name === 'string' ) {
-               this.registry[name] = data;
-               this.emit( 'register', name, data );
        } else {
-               throw new Error( 'Name must be a string or array of strings, cannot be a ' + typeof name );
+               throw new Error( 'Name must be a string or array, cannot be a ' + typeof name );
        }
 };
 
 /**
- * Gets data for a given symbolic name.
+ * Get data for a given symbolic name.
  *
  * Lookups are done using the base name.
  *
- * @method
  * @param {string} name Symbolic name
- * @returns {Mixed|undefined} Data associated with symbolic name
+ * @return {Mixed|undefined} Data associated with symbolic name
  */
 oo.Registry.prototype.lookup = function ( name ) {
        return this.registry[name];
 };
 /**
- * Object factory.
- *
  * @class OO.Factory
  * @extends OO.Registry
  *
  * @constructor
  */
 oo.Factory = function OoFactory() {
-       // Parent constructor
-       oo.Registry.call( this );
+       oo.Factory.super.call( this );
 
        // Properties
        this.entries = [];
@@ -784,14 +767,12 @@ oo.inheritClass( oo.Factory, oo.Registry );
  *
  * Classes must have a static `name` property to be registered.
  *
- *     @example
  *     function MyClass() {};
  *     // Adds a static property to the class defining a symbolic name
  *     MyClass.static = { 'name': 'mine' };
  *     // Registers class with factory, available via symbolic name 'mine'
  *     factory.register( MyClass );
  *
- * @method
  * @param {Function} constructor Constructor to use when creating object
  * @throws {Error} Name must be a string and must not be empty
  * @throws {Error} Constructor must be a function
@@ -807,7 +788,8 @@ oo.Factory.prototype.register = function ( constructor ) {
                throw new Error( 'Name must be a string and must not be empty' );
        }
        this.entries.push( name );
-       oo.Registry.prototype.register.call( this, name, constructor );
+
+       oo.Factory.super.prototype.register.call( this, name, constructor );
 };
 
 /**
@@ -816,10 +798,9 @@ oo.Factory.prototype.register = function ( constructor ) {
  * Name is used to look up the constructor to use, while all additional arguments are passed to the
  * constructor directly, so leaving one out will pass an undefined to the constructor.
  *
- * @method
  * @param {string} name Object name
  * @param {Mixed...} [args] Arguments to pass to the constructor
- * @returns {Object} The new object
+ * @return {Object} The new object
  * @throws {Error} Unknown object name
  */
 oo.Factory.prototype.create = function ( name ) {
diff --git a/resources/sinonjs/sinon-1.8.1.js b/resources/sinonjs/sinon-1.8.1.js
deleted file mode 100644 (file)
index 3e9865e..0000000
+++ /dev/null
@@ -1,4721 +0,0 @@
-/**
- * Sinon.JS 1.8.1, 2014/02/02
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
- *
- * (The BSD License)
- * 
- * Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 
- *     * Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright notice,
- *       this list of conditions and the following disclaimer in the documentation
- *       and/or other materials provided with the distribution.
- *     * Neither the name of Christian Johansen nor the names of his contributors
- *       may be used to endorse or promote products derived from this software
- *       without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-this.sinon = (function () {
-var samsam, formatio;
-function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else { formatio = fn(samsam); } }
-define.amd = true;
-((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
- (typeof module === "object" &&
-      function (m) { module.exports = m(); }) || // Node
- function (m) { this.samsam = m(); } // Browser globals
-)(function () {
-    var o = Object.prototype;
-    var div = typeof document !== "undefined" && document.createElement("div");
-
-    function isNaN(value) {
-        // Unlike global isNaN, this avoids type coercion
-        // typeof check avoids IE host object issues, hat tip to
-        // lodash
-        var val = value; // JsLint thinks value !== value is "weird"
-        return typeof value === "number" && value !== val;
-    }
-
-    function getClass(value) {
-        // Returns the internal [[Class]] by calling Object.prototype.toString
-        // with the provided value as this. Return value is a string, naming the
-        // internal class, e.g. "Array"
-        return o.toString.call(value).split(/[ \]]/)[1];
-    }
-
-    /**
-     * @name samsam.isArguments
-     * @param Object object
-     *
-     * Returns ``true`` if ``object`` is an ``arguments`` object,
-     * ``false`` otherwise.
-     */
-    function isArguments(object) {
-        if (typeof object !== "object" || typeof object.length !== "number" ||
-                getClass(object) === "Array") {
-            return false;
-        }
-        if (typeof object.callee == "function") { return true; }
-        try {
-            object[object.length] = 6;
-            delete object[object.length];
-        } catch (e) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @name samsam.isElement
-     * @param Object object
-     *
-     * Returns ``true`` if ``object`` is a DOM element node. Unlike
-     * Underscore.js/lodash, this function will return ``false`` if ``object``
-     * is an *element-like* object, i.e. a regular object with a ``nodeType``
-     * property that holds the value ``1``.
-     */
-    function isElement(object) {
-        if (!object || object.nodeType !== 1 || !div) { return false; }
-        try {
-            object.appendChild(div);
-            object.removeChild(div);
-        } catch (e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @name samsam.keys
-     * @param Object object
-     *
-     * Return an array of own property names.
-     */
-    function keys(object) {
-        var ks = [], prop;
-        for (prop in object) {
-            if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
-        }
-        return ks;
-    }
-
-    /**
-     * @name samsam.isDate
-     * @param Object value
-     *
-     * Returns true if the object is a ``Date``, or *date-like*. Duck typing
-     * of date objects work by checking that the object has a ``getTime``
-     * function whose return value equals the return value from the object's
-     * ``valueOf``.
-     */
-    function isDate(value) {
-        return typeof value.getTime == "function" &&
-            value.getTime() == value.valueOf();
-    }
-
-    /**
-     * @name samsam.isNegZero
-     * @param Object value
-     *
-     * Returns ``true`` if ``value`` is ``-0``.
-     */
-    function isNegZero(value) {
-        return value === 0 && 1 / value === -Infinity;
-    }
-
-    /**
-     * @name samsam.equal
-     * @param Object obj1
-     * @param Object obj2
-     *
-     * Returns ``true`` if two objects are strictly equal. Compared to
-     * ``===`` there are two exceptions:
-     *
-     *   - NaN is considered equal to NaN
-     *   - -0 and +0 are not considered equal
-     */
-    function identical(obj1, obj2) {
-        if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
-            return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
-        }
-    }
-
-
-    /**
-     * @name samsam.deepEqual
-     * @param Object obj1
-     * @param Object obj2
-     *
-     * Deep equal comparison. Two values are "deep equal" if:
-     *
-     *   - They are equal, according to samsam.identical
-     *   - They are both date objects representing the same time
-     *   - They are both arrays containing elements that are all deepEqual
-     *   - They are objects with the same set of properties, and each property
-     *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
-     *
-     * Supports cyclic objects.
-     */
-    function deepEqualCyclic(obj1, obj2) {
-
-        // used for cyclic comparison
-        // contain already visited objects
-        var objects1 = [],
-            objects2 = [],
-        // contain pathes (position in the object structure)
-        // of the already visited objects
-        // indexes same as in objects arrays
-            paths1 = [],
-            paths2 = [],
-        // contains combinations of already compared objects
-        // in the manner: { "$1['ref']$2['ref']": true }
-            compared = {};
-
-        /**
-         * used to check, if the value of a property is an object
-         * (cyclic logic is only needed for objects)
-         * only needed for cyclic logic
-         */
-        function isObject(value) {
-
-            if (typeof value === 'object' && value !== null &&
-                    !(value instanceof Boolean) &&
-                    !(value instanceof Date)    &&
-                    !(value instanceof Number)  &&
-                    !(value instanceof RegExp)  &&
-                    !(value instanceof String)) {
-
-                return true;
-            }
-
-            return false;
-        }
-
-        /**
-         * returns the index of the given object in the
-         * given objects array, -1 if not contained
-         * only needed for cyclic logic
-         */
-        function getIndex(objects, obj) {
-
-            var i;
-            for (i = 0; i < objects.length; i++) {
-                if (objects[i] === obj) {
-                    return i;
-                }
-            }
-
-            return -1;
-        }
-
-        // does the recursion for the deep equal check
-        return (function deepEqual(obj1, obj2, path1, path2) {
-            var type1 = typeof obj1;
-            var type2 = typeof obj2;
-
-            // == null also matches undefined
-            if (obj1 === obj2 ||
-                    isNaN(obj1) || isNaN(obj2) ||
-                    obj1 == null || obj2 == null ||
-                    type1 !== "object" || type2 !== "object") {
-
-                return identical(obj1, obj2);
-            }
-
-            // Elements are only equal if identical(expected, actual)
-            if (isElement(obj1) || isElement(obj2)) { return false; }
-
-            var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
-            if (isDate1 || isDate2) {
-                if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
-                    return false;
-                }
-            }
-
-            if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
-                if (obj1.toString() !== obj2.toString()) { return false; }
-            }
-
-            var class1 = getClass(obj1);
-            var class2 = getClass(obj2);
-            var keys1 = keys(obj1);
-            var keys2 = keys(obj2);
-
-            if (isArguments(obj1) || isArguments(obj2)) {
-                if (obj1.length !== obj2.length) { return false; }
-            } else {
-                if (type1 !== type2 || class1 !== class2 ||
-                        keys1.length !== keys2.length) {
-                    return false;
-                }
-            }
-
-            var key, i, l,
-                // following vars are used for the cyclic logic
-                value1, value2,
-                isObject1, isObject2,
-                index1, index2,
-                newPath1, newPath2;
-
-            for (i = 0, l = keys1.length; i < l; i++) {
-                key = keys1[i];
-                if (!o.hasOwnProperty.call(obj2, key)) {
-                    return false;
-                }
-
-                // Start of the cyclic logic
-
-                value1 = obj1[key];
-                value2 = obj2[key];
-
-                isObject1 = isObject(value1);
-                isObject2 = isObject(value2);
-
-                // determine, if the objects were already visited
-                // (it's faster to check for isObject first, than to
-                // get -1 from getIndex for non objects)
-                index1 = isObject1 ? getIndex(objects1, value1) : -1;
-                index2 = isObject2 ? getIndex(objects2, value2) : -1;
-
-                // determine the new pathes of the objects
-                // - for non cyclic objects the current path will be extended
-                //   by current property name
-                // - for cyclic objects the stored path is taken
-                newPath1 = index1 !== -1
-                    ? paths1[index1]
-                    : path1 + '[' + JSON.stringify(key) + ']';
-                newPath2 = index2 !== -1
-                    ? paths2[index2]
-                    : path2 + '[' + JSON.stringify(key) + ']';
-
-                // stop recursion if current objects are already compared
-                if (compared[newPath1 + newPath2]) {
-                    return true;
-                }
-
-                // remember the current objects and their pathes
-                if (index1 === -1 && isObject1) {
-                    objects1.push(value1);
-                    paths1.push(newPath1);
-                }
-                if (index2 === -1 && isObject2) {
-                    objects2.push(value2);
-                    paths2.push(newPath2);
-                }
-
-                // remember that the current objects are already compared
-                if (isObject1 && isObject2) {
-                    compared[newPath1 + newPath2] = true;
-                }
-
-                // End of cyclic logic
-
-                // neither value1 nor value2 is a cycle
-                // continue with next level
-                if (!deepEqual(value1, value2, newPath1, newPath2)) {
-                    return false;
-                }
-            }
-
-            return true;
-
-        }(obj1, obj2, '$1', '$2'));
-    }
-
-    var match;
-
-    function arrayContains(array, subset) {
-        if (subset.length === 0) { return true; }
-        var i, l, j, k;
-        for (i = 0, l = array.length; i < l; ++i) {
-            if (match(array[i], subset[0])) {
-                for (j = 0, k = subset.length; j < k; ++j) {
-                    if (!match(array[i + j], subset[j])) { return false; }
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @name samsam.match
-     * @param Object object
-     * @param Object matcher
-     *
-     * Compare arbitrary value ``object`` with matcher.
-     */
-    match = function match(object, matcher) {
-        if (matcher && typeof matcher.test === "function") {
-            return matcher.test(object);
-        }
-
-        if (typeof matcher === "function") {
-            return matcher(object) === true;
-        }
-
-        if (typeof matcher === "string") {
-            matcher = matcher.toLowerCase();
-            var notNull = typeof object === "string" || !!object;
-            return notNull &&
-                (String(object)).toLowerCase().indexOf(matcher) >= 0;
-        }
-
-        if (typeof matcher === "number") {
-            return matcher === object;
-        }
-
-        if (typeof matcher === "boolean") {
-            return matcher === object;
-        }
-
-        if (getClass(object) === "Array" && getClass(matcher) === "Array") {
-            return arrayContains(object, matcher);
-        }
-
-        if (matcher && typeof matcher === "object") {
-            var prop;
-            for (prop in matcher) {
-                if (!match(object[prop], matcher[prop])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        throw new Error("Matcher was not a string, a number, a " +
-                        "function, a boolean or an object");
-    };
-
-    return {
-        isArguments: isArguments,
-        isElement: isElement,
-        isDate: isDate,
-        isNegZero: isNegZero,
-        identical: identical,
-        deepEqual: deepEqualCyclic,
-        match: match,
-        keys: keys
-    };
-});
-((typeof define === "function" && define.amd && function (m) {
-    define("formatio", ["samsam"], m);
-}) || (typeof module === "object" && function (m) {
-    module.exports = m(require("samsam"));
-}) || function (m) { this.formatio = m(this.samsam); }
-)(function (samsam) {
-    
-    var formatio = {
-        excludeConstructors: ["Object", /^.$/],
-        quoteStrings: true
-    };
-
-    var hasOwn = Object.prototype.hasOwnProperty;
-
-    var specialObjects = [];
-    if (typeof global !== "undefined") {
-        specialObjects.push({ object: global, value: "[object global]" });
-    }
-    if (typeof document !== "undefined") {
-        specialObjects.push({
-            object: document,
-            value: "[object HTMLDocument]"
-        });
-    }
-    if (typeof window !== "undefined") {
-        specialObjects.push({ object: window, value: "[object Window]" });
-    }
-
-    function functionName(func) {
-        if (!func) { return ""; }
-        if (func.displayName) { return func.displayName; }
-        if (func.name) { return func.name; }
-        var matches = func.toString().match(/function\s+([^\(]+)/m);
-        return (matches && matches[1]) || "";
-    }
-
-    function constructorName(f, object) {
-        var name = functionName(object && object.constructor);
-        var excludes = f.excludeConstructors ||
-                formatio.excludeConstructors || [];
-
-        var i, l;
-        for (i = 0, l = excludes.length; i < l; ++i) {
-            if (typeof excludes[i] === "string" && excludes[i] === name) {
-                return "";
-            } else if (excludes[i].test && excludes[i].test(name)) {
-                return "";
-            }
-        }
-
-        return name;
-    }
-
-    function isCircular(object, objects) {
-        if (typeof object !== "object") { return false; }
-        var i, l;
-        for (i = 0, l = objects.length; i < l; ++i) {
-            if (objects[i] === object) { return true; }
-        }
-        return false;
-    }
-
-    function ascii(f, object, processed, indent) {
-        if (typeof object === "string") {
-            var qs = f.quoteStrings;
-            var quote = typeof qs !== "boolean" || qs;
-            return processed || quote ? '"' + object + '"' : object;
-        }
-
-        if (typeof object === "function" && !(object instanceof RegExp)) {
-            return ascii.func(object);
-        }
-
-        processed = processed || [];
-
-        if (isCircular(object, processed)) { return "[Circular]"; }
-
-        if (Object.prototype.toString.call(object) === "[object Array]") {
-            return ascii.array.call(f, object, processed);
-        }
-
-        if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
-        if (samsam.isElement(object)) { return ascii.element(object); }
-
-        if (typeof object.toString === "function" &&
-                object.toString !== Object.prototype.toString) {
-            return object.toString();
-        }
-
-        var i, l;
-        for (i = 0, l = specialObjects.length; i < l; i++) {
-            if (object === specialObjects[i].object) {
-                return specialObjects[i].value;
-            }
-        }
-
-        return ascii.object.call(f, object, processed, indent);
-    }
-
-    ascii.func = function (func) {
-        return "function " + functionName(func) + "() {}";
-    };
-
-    ascii.array = function (array, processed) {
-        processed = processed || [];
-        processed.push(array);
-        var i, l, pieces = [];
-        for (i = 0, l = array.length; i < l; ++i) {
-            pieces.push(ascii(this, array[i], processed));
-        }
-        return "[" + pieces.join(", ") + "]";
-    };
-
-    ascii.object = function (object, processed, indent) {
-        processed = processed || [];
-        processed.push(object);
-        indent = indent || 0;
-        var pieces = [], properties = samsam.keys(object).sort();
-        var length = 3;
-        var prop, str, obj, i, l;
-
-        for (i = 0, l = properties.length; i < l; ++i) {
-            prop = properties[i];
-            obj = object[prop];
-
-            if (isCircular(obj, processed)) {
-                str = "[Circular]";
-            } else {
-                str = ascii(this, obj, processed, indent + 2);
-            }
-
-            str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
-            length += str.length;
-            pieces.push(str);
-        }
-
-        var cons = constructorName(this, object);
-        var prefix = cons ? "[" + cons + "] " : "";
-        var is = "";
-        for (i = 0, l = indent; i < l; ++i) { is += " "; }
-
-        if (length + indent > 80) {
-            return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
-                is + "}";
-        }
-        return prefix + "{ " + pieces.join(", ") + " }";
-    };
-
-    ascii.element = function (element) {
-        var tagName = element.tagName.toLowerCase();
-        var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
-
-        for (i = 0, l = attrs.length; i < l; ++i) {
-            attr = attrs.item(i);
-            attrName = attr.nodeName.toLowerCase().replace("html:", "");
-            val = attr.nodeValue;
-            if (attrName !== "contenteditable" || val !== "inherit") {
-                if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
-            }
-        }
-
-        var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
-        var content = element.innerHTML;
-
-        if (content.length > 20) {
-            content = content.substr(0, 20) + "[...]";
-        }
-
-        var res = formatted + pairs.join(" ") + ">" + content +
-                "</" + tagName + ">";
-
-        return res.replace(/ contentEditable="inherit"/, "");
-    };
-
-    function Formatio(options) {
-        for (var opt in options) {
-            this[opt] = options[opt];
-        }
-    }
-
-    Formatio.prototype = {
-        functionName: functionName,
-
-        configure: function (options) {
-            return new Formatio(options);
-        },
-
-        constructorName: function (object) {
-            return constructorName(this, object);
-        },
-
-        ascii: function (object, processed, indent) {
-            return ascii(this, object, processed, indent);
-        }
-    };
-
-    return Formatio.prototype;
-});
-/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
-/*global module, require, __dirname, document*/
-/**
- * Sinon core utilities. For internal use only.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-var sinon = (function (formatio) {
-    var div = typeof document != "undefined" && document.createElement("div");
-    var hasOwn = Object.prototype.hasOwnProperty;
-
-    function isDOMNode(obj) {
-        var success = false;
-
-        try {
-            obj.appendChild(div);
-            success = div.parentNode == obj;
-        } catch (e) {
-            return false;
-        } finally {
-            try {
-                obj.removeChild(div);
-            } catch (e) {
-                // Remove failed, not much we can do about that
-            }
-        }
-
-        return success;
-    }
-
-    function isElement(obj) {
-        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
-    }
-
-    function isFunction(obj) {
-        return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
-    }
-
-    function mirrorProperties(target, source) {
-        for (var prop in source) {
-            if (!hasOwn.call(target, prop)) {
-                target[prop] = source[prop];
-            }
-        }
-    }
-
-    function isRestorable (obj) {
-        return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
-    }
-
-    var sinon = {
-        wrapMethod: function wrapMethod(object, property, method) {
-            if (!object) {
-                throw new TypeError("Should wrap property of object");
-            }
-
-            if (typeof method != "function") {
-                throw new TypeError("Method wrapper should be function");
-            }
-
-            var wrappedMethod = object[property],
-                error;
-
-            if (!isFunction(wrappedMethod)) {
-                error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
-                                    property + " as function");
-            }
-
-            if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
-                error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
-            }
-
-            if (wrappedMethod.calledBefore) {
-                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
-                error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
-            }
-
-            if (error) {
-                if (wrappedMethod._stack) {
-                    error.stack += '\n--------------\n' + wrappedMethod._stack;
-                }
-                throw error;
-            }
-
-            // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
-            // when using hasOwn.call on objects from other frames.
-            var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
-            object[property] = method;
-            method.displayName = property;
-            // Set up a stack trace which can be used later to find what line of
-            // code the original method was created on.
-            method._stack = (new Error('Stack Trace for original')).stack;
-
-            method.restore = function () {
-                // For prototype properties try to reset by delete first.
-                // If this fails (ex: localStorage on mobile safari) then force a reset
-                // via direct assignment.
-                if (!owned) {
-                    delete object[property];
-                }
-                if (object[property] === method) {
-                    object[property] = wrappedMethod;
-                }
-            };
-
-            method.restore.sinon = true;
-            mirrorProperties(method, wrappedMethod);
-
-            return method;
-        },
-
-        extend: function extend(target) {
-            for (var i = 1, l = arguments.length; i < l; i += 1) {
-                for (var prop in arguments[i]) {
-                    if (arguments[i].hasOwnProperty(prop)) {
-                        target[prop] = arguments[i][prop];
-                    }
-
-                    // DONT ENUM bug, only care about toString
-                    if (arguments[i].hasOwnProperty("toString") &&
-                        arguments[i].toString != target.toString) {
-                        target.toString = arguments[i].toString;
-                    }
-                }
-            }
-
-            return target;
-        },
-
-        create: function create(proto) {
-            var F = function () {};
-            F.prototype = proto;
-            return new F();
-        },
-
-        deepEqual: function deepEqual(a, b) {
-            if (sinon.match && sinon.match.isMatcher(a)) {
-                return a.test(b);
-            }
-            if (typeof a != "object" || typeof b != "object") {
-                return a === b;
-            }
-
-            if (isElement(a) || isElement(b)) {
-                return a === b;
-            }
-
-            if (a === b) {
-                return true;
-            }
-
-            if ((a === null && b !== null) || (a !== null && b === null)) {
-                return false;
-            }
-
-            var aString = Object.prototype.toString.call(a);
-            if (aString != Object.prototype.toString.call(b)) {
-                return false;
-            }
-
-            if (aString == "[object Date]") {
-                return a.valueOf() === b.valueOf();
-            }
-
-            var prop, aLength = 0, bLength = 0;
-
-            if (aString == "[object Array]" && a.length !== b.length) {
-                return false;
-            }
-
-            for (prop in a) {
-                aLength += 1;
-
-                if (!deepEqual(a[prop], b[prop])) {
-                    return false;
-                }
-            }
-
-            for (prop in b) {
-                bLength += 1;
-            }
-
-            return aLength == bLength;
-        },
-
-        functionName: function functionName(func) {
-            var name = func.displayName || func.name;
-
-            // Use function decomposition as a last resort to get function
-            // name. Does not rely on function decomposition to work - if it
-            // doesn't debugging will be slightly less informative
-            // (i.e. toString will say 'spy' rather than 'myFunc').
-            if (!name) {
-                var matches = func.toString().match(/function ([^\s\(]+)/);
-                name = matches && matches[1];
-            }
-
-            return name;
-        },
-
-        functionToString: function toString() {
-            if (this.getCall && this.callCount) {
-                var thisValue, prop, i = this.callCount;
-
-                while (i--) {
-                    thisValue = this.getCall(i).thisValue;
-
-                    for (prop in thisValue) {
-                        if (thisValue[prop] === this) {
-                            return prop;
-                        }
-                    }
-                }
-            }
-
-            return this.displayName || "sinon fake";
-        },
-
-        getConfig: function (custom) {
-            var config = {};
-            custom = custom || {};
-            var defaults = sinon.defaultConfig;
-
-            for (var prop in defaults) {
-                if (defaults.hasOwnProperty(prop)) {
-                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
-                }
-            }
-
-            return config;
-        },
-
-        format: function (val) {
-            return "" + val;
-        },
-
-        defaultConfig: {
-            injectIntoThis: true,
-            injectInto: null,
-            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
-            useFakeTimers: true,
-            useFakeServer: true
-        },
-
-        timesInWords: function timesInWords(count) {
-            return count == 1 && "once" ||
-                count == 2 && "twice" ||
-                count == 3 && "thrice" ||
-                (count || 0) + " times";
-        },
-
-        calledInOrder: function (spies) {
-            for (var i = 1, l = spies.length; i < l; i++) {
-                if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
-                    return false;
-                }
-            }
-
-            return true;
-        },
-
-        orderByFirstCall: function (spies) {
-            return spies.sort(function (a, b) {
-                // uuid, won't ever be equal
-                var aCall = a.getCall(0);
-                var bCall = b.getCall(0);
-                var aId = aCall && aCall.callId || -1;
-                var bId = bCall && bCall.callId || -1;
-
-                return aId < bId ? -1 : 1;
-            });
-        },
-
-        log: function () {},
-
-        logError: function (label, err) {
-            var msg = label + " threw exception: ";
-            sinon.log(msg + "[" + err.name + "] " + err.message);
-            if (err.stack) { sinon.log(err.stack); }
-
-            setTimeout(function () {
-                err.message = msg + err.message;
-                throw err;
-            }, 0);
-        },
-
-        typeOf: function (value) {
-            if (value === null) {
-                return "null";
-            }
-            else if (value === undefined) {
-                return "undefined";
-            }
-            var string = Object.prototype.toString.call(value);
-            return string.substring(8, string.length - 1).toLowerCase();
-        },
-
-        createStubInstance: function (constructor) {
-            if (typeof constructor !== "function") {
-                throw new TypeError("The constructor should be a function.");
-            }
-            return sinon.stub(sinon.create(constructor.prototype));
-        },
-
-        restore: function (object) {
-            if (object !== null && typeof object === "object") {
-                for (var prop in object) {
-                    if (isRestorable(object[prop])) {
-                        object[prop].restore();
-                    }
-                }
-            }
-            else if (isRestorable(object)) {
-                object.restore();
-            }
-        }
-    };
-
-    var isNode = typeof module !== "undefined" && module.exports;
-    var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
-
-    if (isAMD) {
-        define(function(){
-            return sinon;
-        });
-    } else if (isNode) {
-        try {
-            formatio = require("formatio");
-        } catch (e) {}
-        module.exports = sinon;
-        module.exports.spy = require("./sinon/spy");
-        module.exports.spyCall = require("./sinon/call");
-        module.exports.behavior = require("./sinon/behavior");
-        module.exports.stub = require("./sinon/stub");
-        module.exports.mock = require("./sinon/mock");
-        module.exports.collection = require("./sinon/collection");
-        module.exports.assert = require("./sinon/assert");
-        module.exports.sandbox = require("./sinon/sandbox");
-        module.exports.test = require("./sinon/test");
-        module.exports.testCase = require("./sinon/test_case");
-        module.exports.assert = require("./sinon/assert");
-        module.exports.match = require("./sinon/match");
-    }
-
-    if (formatio) {
-        var formatter = formatio.configure({ quoteStrings: false });
-        sinon.format = function () {
-            return formatter.ascii.apply(formatter, arguments);
-        };
-    } else if (isNode) {
-        try {
-            var util = require("util");
-            sinon.format = function (value) {
-                return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
-            };
-        } catch (e) {
-            /* Node, but no util module - would be very old, but better safe than
-             sorry */
-        }
-    }
-
-    return sinon;
-}(typeof formatio == "object" && formatio));
-
-/* @depend ../sinon.js */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Match functions
- *
- * @author Maximilian Antoni (mail@maxantoni.de)
- * @license BSD
- *
- * Copyright (c) 2012 Maximilian Antoni
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function assertType(value, type, name) {
-        var actual = sinon.typeOf(value);
-        if (actual !== type) {
-            throw new TypeError("Expected type of " + name + " to be " +
-                type + ", but was " + actual);
-        }
-    }
-
-    var matcher = {
-        toString: function () {
-            return this.message;
-        }
-    };
-
-    function isMatcher(object) {
-        return matcher.isPrototypeOf(object);
-    }
-
-    function matchObject(expectation, actual) {
-        if (actual === null || actual === undefined) {
-            return false;
-        }
-        for (var key in expectation) {
-            if (expectation.hasOwnProperty(key)) {
-                var exp = expectation[key];
-                var act = actual[key];
-                if (match.isMatcher(exp)) {
-                    if (!exp.test(act)) {
-                        return false;
-                    }
-                } else if (sinon.typeOf(exp) === "object") {
-                    if (!matchObject(exp, act)) {
-                        return false;
-                    }
-                } else if (!sinon.deepEqual(exp, act)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    matcher.or = function (m2) {
-        if (!isMatcher(m2)) {
-            throw new TypeError("Matcher expected");
-        }
-        var m1 = this;
-        var or = sinon.create(matcher);
-        or.test = function (actual) {
-            return m1.test(actual) || m2.test(actual);
-        };
-        or.message = m1.message + ".or(" + m2.message + ")";
-        return or;
-    };
-
-    matcher.and = function (m2) {
-        if (!isMatcher(m2)) {
-            throw new TypeError("Matcher expected");
-        }
-        var m1 = this;
-        var and = sinon.create(matcher);
-        and.test = function (actual) {
-            return m1.test(actual) && m2.test(actual);
-        };
-        and.message = m1.message + ".and(" + m2.message + ")";
-        return and;
-    };
-
-    var match = function (expectation, message) {
-        var m = sinon.create(matcher);
-        var type = sinon.typeOf(expectation);
-        switch (type) {
-        case "object":
-            if (typeof expectation.test === "function") {
-                m.test = function (actual) {
-                    return expectation.test(actual) === true;
-                };
-                m.message = "match(" + sinon.functionName(expectation.test) + ")";
-                return m;
-            }
-            var str = [];
-            for (var key in expectation) {
-                if (expectation.hasOwnProperty(key)) {
-                    str.push(key + ": " + expectation[key]);
-                }
-            }
-            m.test = function (actual) {
-                return matchObject(expectation, actual);
-            };
-            m.message = "match(" + str.join(", ") + ")";
-            break;
-        case "number":
-            m.test = function (actual) {
-                return expectation == actual;
-            };
-            break;
-        case "string":
-            m.test = function (actual) {
-                if (typeof actual !== "string") {
-                    return false;
-                }
-                return actual.indexOf(expectation) !== -1;
-            };
-            m.message = "match(\"" + expectation + "\")";
-            break;
-        case "regexp":
-            m.test = function (actual) {
-                if (typeof actual !== "string") {
-                    return false;
-                }
-                return expectation.test(actual);
-            };
-            break;
-        case "function":
-            m.test = expectation;
-            if (message) {
-                m.message = message;
-            } else {
-                m.message = "match(" + sinon.functionName(expectation) + ")";
-            }
-            break;
-        default:
-            m.test = function (actual) {
-              return sinon.deepEqual(expectation, actual);
-            };
-        }
-        if (!m.message) {
-            m.message = "match(" + expectation + ")";
-        }
-        return m;
-    };
-
-    match.isMatcher = isMatcher;
-
-    match.any = match(function () {
-        return true;
-    }, "any");
-
-    match.defined = match(function (actual) {
-        return actual !== null && actual !== undefined;
-    }, "defined");
-
-    match.truthy = match(function (actual) {
-        return !!actual;
-    }, "truthy");
-
-    match.falsy = match(function (actual) {
-        return !actual;
-    }, "falsy");
-
-    match.same = function (expectation) {
-        return match(function (actual) {
-            return expectation === actual;
-        }, "same(" + expectation + ")");
-    };
-
-    match.typeOf = function (type) {
-        assertType(type, "string", "type");
-        return match(function (actual) {
-            return sinon.typeOf(actual) === type;
-        }, "typeOf(\"" + type + "\")");
-    };
-
-    match.instanceOf = function (type) {
-        assertType(type, "function", "type");
-        return match(function (actual) {
-            return actual instanceof type;
-        }, "instanceOf(" + sinon.functionName(type) + ")");
-    };
-
-    function createPropertyMatcher(propertyTest, messagePrefix) {
-        return function (property, value) {
-            assertType(property, "string", "property");
-            var onlyProperty = arguments.length === 1;
-            var message = messagePrefix + "(\"" + property + "\"";
-            if (!onlyProperty) {
-                message += ", " + value;
-            }
-            message += ")";
-            return match(function (actual) {
-                if (actual === undefined || actual === null ||
-                        !propertyTest(actual, property)) {
-                    return false;
-                }
-                return onlyProperty || sinon.deepEqual(value, actual[property]);
-            }, message);
-        };
-    }
-
-    match.has = createPropertyMatcher(function (actual, property) {
-        if (typeof actual === "object") {
-            return property in actual;
-        }
-        return actual[property] !== undefined;
-    }, "has");
-
-    match.hasOwn = createPropertyMatcher(function (actual, property) {
-        return actual.hasOwnProperty(property);
-    }, "hasOwn");
-
-    match.bool = match.typeOf("boolean");
-    match.number = match.typeOf("number");
-    match.string = match.typeOf("string");
-    match.object = match.typeOf("object");
-    match.func = match.typeOf("function");
-    match.array = match.typeOf("array");
-    match.regexp = match.typeOf("regexp");
-    match.date = match.typeOf("date");
-
-    if (commonJSModule) {
-        module.exports = match;
-    } else {
-        sinon.match = match;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
-  * @depend ../sinon.js
-  * @depend match.js
-  */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
-  * Spy calls
-  *
-  * @author Christian Johansen (christian@cjohansen.no)
-  * @author Maximilian Antoni (mail@maxantoni.de)
-  * @license BSD
-  *
-  * Copyright (c) 2010-2013 Christian Johansen
-  * Copyright (c) 2013 Maximilian Antoni
-  */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function throwYieldError(proxy, text, args) {
-        var msg = sinon.functionName(proxy) + text;
-        if (args.length) {
-            msg += " Received [" + slice.call(args).join(", ") + "]";
-        }
-        throw new Error(msg);
-    }
-
-    var slice = Array.prototype.slice;
-
-    var callProto = {
-        calledOn: function calledOn(thisValue) {
-            if (sinon.match && sinon.match.isMatcher(thisValue)) {
-                return thisValue.test(this.thisValue);
-            }
-            return this.thisValue === thisValue;
-        },
-
-        calledWith: function calledWith() {
-            for (var i = 0, l = arguments.length; i < l; i += 1) {
-                if (!sinon.deepEqual(arguments[i], this.args[i])) {
-                    return false;
-                }
-            }
-
-            return true;
-        },
-
-        calledWithMatch: function calledWithMatch() {
-            for (var i = 0, l = arguments.length; i < l; i += 1) {
-                var actual = this.args[i];
-                var expectation = arguments[i];
-                if (!sinon.match || !sinon.match(expectation).test(actual)) {
-                    return false;
-                }
-            }
-            return true;
-        },
-
-        calledWithExactly: function calledWithExactly() {
-            return arguments.length == this.args.length &&
-                this.calledWith.apply(this, arguments);
-        },
-
-        notCalledWith: function notCalledWith() {
-            return !this.calledWith.apply(this, arguments);
-        },
-
-        notCalledWithMatch: function notCalledWithMatch() {
-            return !this.calledWithMatch.apply(this, arguments);
-        },
-
-        returned: function returned(value) {
-            return sinon.deepEqual(value, this.returnValue);
-        },
-
-        threw: function threw(error) {
-            if (typeof error === "undefined" || !this.exception) {
-                return !!this.exception;
-            }
-
-            return this.exception === error || this.exception.name === error;
-        },
-
-        calledWithNew: function calledWithNew() {
-            return this.thisValue instanceof this.proxy;
-        },
-
-        calledBefore: function (other) {
-            return this.callId < other.callId;
-        },
-
-        calledAfter: function (other) {
-            return this.callId > other.callId;
-        },
-
-        callArg: function (pos) {
-            this.args[pos]();
-        },
-
-        callArgOn: function (pos, thisValue) {
-            this.args[pos].apply(thisValue);
-        },
-
-        callArgWith: function (pos) {
-            this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
-        },
-
-        callArgOnWith: function (pos, thisValue) {
-            var args = slice.call(arguments, 2);
-            this.args[pos].apply(thisValue, args);
-        },
-
-        "yield": function () {
-            this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
-        },
-
-        yieldOn: function (thisValue) {
-            var args = this.args;
-            for (var i = 0, l = args.length; i < l; ++i) {
-                if (typeof args[i] === "function") {
-                    args[i].apply(thisValue, slice.call(arguments, 1));
-                    return;
-                }
-            }
-            throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
-        },
-
-        yieldTo: function (prop) {
-            this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
-        },
-
-        yieldToOn: function (prop, thisValue) {
-            var args = this.args;
-            for (var i = 0, l = args.length; i < l; ++i) {
-                if (args[i] && typeof args[i][prop] === "function") {
-                    args[i][prop].apply(thisValue, slice.call(arguments, 2));
-                    return;
-                }
-            }
-            throwYieldError(this.proxy, " cannot yield to '" + prop +
-                "' since no callback was passed.", args);
-        },
-
-        toString: function () {
-            var callStr = this.proxy.toString() + "(";
-            var args = [];
-
-            for (var i = 0, l = this.args.length; i < l; ++i) {
-                args.push(sinon.format(this.args[i]));
-            }
-
-            callStr = callStr + args.join(", ") + ")";
-
-            if (typeof this.returnValue != "undefined") {
-                callStr += " => " + sinon.format(this.returnValue);
-            }
-
-            if (this.exception) {
-                callStr += " !" + this.exception.name;
-
-                if (this.exception.message) {
-                    callStr += "(" + this.exception.message + ")";
-                }
-            }
-
-            return callStr;
-        }
-    };
-
-    callProto.invokeCallback = callProto.yield;
-
-    function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
-        if (typeof id !== "number") {
-            throw new TypeError("Call id is not a number");
-        }
-        var proxyCall = sinon.create(callProto);
-        proxyCall.proxy = spy;
-        proxyCall.thisValue = thisValue;
-        proxyCall.args = args;
-        proxyCall.returnValue = returnValue;
-        proxyCall.exception = exception;
-        proxyCall.callId = id;
-
-        return proxyCall;
-    }
-    createSpyCall.toString = callProto.toString; // used by mocks
-
-    if (commonJSModule) {
-        module.exports = createSpyCall;
-    } else {
-        sinon.spyCall = createSpyCall;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-
-/**
-  * @depend ../sinon.js
-  * @depend call.js
-  */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
-  * Spy functions
-  *
-  * @author Christian Johansen (christian@cjohansen.no)
-  * @license BSD
-  *
-  * Copyright (c) 2010-2013 Christian Johansen
-  */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-    var push = Array.prototype.push;
-    var slice = Array.prototype.slice;
-    var callId = 0;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function spy(object, property) {
-        if (!property && typeof object == "function") {
-            return spy.create(object);
-        }
-
-        if (!object && !property) {
-            return spy.create(function () { });
-        }
-
-        var method = object[property];
-        return sinon.wrapMethod(object, property, spy.create(method));
-    }
-
-    function matchingFake(fakes, args, strict) {
-        if (!fakes) {
-            return;
-        }
-
-        for (var i = 0, l = fakes.length; i < l; i++) {
-            if (fakes[i].matches(args, strict)) {
-                return fakes[i];
-            }
-        }
-    }
-
-    function incrementCallCount() {
-        this.called = true;
-        this.callCount += 1;
-        this.notCalled = false;
-        this.calledOnce = this.callCount == 1;
-        this.calledTwice = this.callCount == 2;
-        this.calledThrice = this.callCount == 3;
-    }
-
-    function createCallProperties() {
-        this.firstCall = this.getCall(0);
-        this.secondCall = this.getCall(1);
-        this.thirdCall = this.getCall(2);
-        this.lastCall = this.getCall(this.callCount - 1);
-    }
-
-    var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
-    function createProxy(func) {
-        // Retain the function length:
-        var p;
-        if (func.length) {
-            eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
-                ") { return p.invoke(func, this, slice.call(arguments)); });");
-        }
-        else {
-            p = function proxy() {
-                return p.invoke(func, this, slice.call(arguments));
-            };
-        }
-        return p;
-    }
-
-    var uuid = 0;
-
-    // Public API
-    var spyApi = {
-        reset: function () {
-            this.called = false;
-            this.notCalled = true;
-            this.calledOnce = false;
-            this.calledTwice = false;
-            this.calledThrice = false;
-            this.callCount = 0;
-            this.firstCall = null;
-            this.secondCall = null;
-            this.thirdCall = null;
-            this.lastCall = null;
-            this.args = [];
-            this.returnValues = [];
-            this.thisValues = [];
-            this.exceptions = [];
-            this.callIds = [];
-            if (this.fakes) {
-                for (var i = 0; i < this.fakes.length; i++) {
-                    this.fakes[i].reset();
-                }
-            }
-        },
-
-        create: function create(func) {
-            var name;
-
-            if (typeof func != "function") {
-                func = function () { };
-            } else {
-                name = sinon.functionName(func);
-            }
-
-            var proxy = createProxy(func);
-
-            sinon.extend(proxy, spy);
-            delete proxy.create;
-            sinon.extend(proxy, func);
-
-            proxy.reset();
-            proxy.prototype = func.prototype;
-            proxy.displayName = name || "spy";
-            proxy.toString = sinon.functionToString;
-            proxy._create = sinon.spy.create;
-            proxy.id = "spy#" + uuid++;
-
-            return proxy;
-        },
-
-        invoke: function invoke(func, thisValue, args) {
-            var matching = matchingFake(this.fakes, args);
-            var exception, returnValue;
-
-            incrementCallCount.call(this);
-            push.call(this.thisValues, thisValue);
-            push.call(this.args, args);
-            push.call(this.callIds, callId++);
-
-            try {
-                if (matching) {
-                    returnValue = matching.invoke(func, thisValue, args);
-                } else {
-                    returnValue = (this.func || func).apply(thisValue, args);
-                }
-
-                var thisCall = this.getCall(this.callCount - 1);
-                if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
-                    returnValue = thisValue;
-                }
-            } catch (e) {
-                exception = e;
-            }
-
-            push.call(this.exceptions, exception);
-            push.call(this.returnValues, returnValue);
-
-            createCallProperties.call(this);
-
-            if (exception !== undefined) {
-                throw exception;
-            }
-
-            return returnValue;
-        },
-
-        getCall: function getCall(i) {
-            if (i < 0 || i >= this.callCount) {
-                return null;
-            }
-
-            return sinon.spyCall(this, this.thisValues[i], this.args[i],
-                                    this.returnValues[i], this.exceptions[i],
-                                    this.callIds[i]);
-        },
-
-        getCalls: function () {
-            var calls = [];
-            var i;
-
-            for (i = 0; i < this.callCount; i++) {
-                calls.push(this.getCall(i));
-            }
-
-            return calls;
-        },
-
-        calledBefore: function calledBefore(spyFn) {
-            if (!this.called) {
-                return false;
-            }
-
-            if (!spyFn.called) {
-                return true;
-            }
-
-            return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
-        },
-
-        calledAfter: function calledAfter(spyFn) {
-            if (!this.called || !spyFn.called) {
-                return false;
-            }
-
-            return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
-        },
-
-        withArgs: function () {
-            var args = slice.call(arguments);
-
-            if (this.fakes) {
-                var match = matchingFake(this.fakes, args, true);
-
-                if (match) {
-                    return match;
-                }
-            } else {
-                this.fakes = [];
-            }
-
-            var original = this;
-            var fake = this._create();
-            fake.matchingAguments = args;
-            fake.parent = this;
-            push.call(this.fakes, fake);
-
-            fake.withArgs = function () {
-                return original.withArgs.apply(original, arguments);
-            };
-
-            for (var i = 0; i < this.args.length; i++) {
-                if (fake.matches(this.args[i])) {
-                    incrementCallCount.call(fake);
-                    push.call(fake.thisValues, this.thisValues[i]);
-                    push.call(fake.args, this.args[i]);
-                    push.call(fake.returnValues, this.returnValues[i]);
-                    push.call(fake.exceptions, this.exceptions[i]);
-                    push.call(fake.callIds, this.callIds[i]);
-                }
-            }
-            createCallProperties.call(fake);
-
-            return fake;
-        },
-
-        matches: function (args, strict) {
-            var margs = this.matchingAguments;
-
-            if (margs.length <= args.length &&
-                sinon.deepEqual(margs, args.slice(0, margs.length))) {
-                return !strict || margs.length == args.length;
-            }
-        },
-
-        printf: function (format) {
-            var spy = this;
-            var args = slice.call(arguments, 1);
-            var formatter;
-
-            return (format || "").replace(/%(.)/g, function (match, specifyer) {
-                formatter = spyApi.formatters[specifyer];
-
-                if (typeof formatter == "function") {
-                    return formatter.call(null, spy, args);
-                } else if (!isNaN(parseInt(specifyer, 10))) {
-                    return sinon.format(args[specifyer - 1]);
-                }
-
-                return "%" + specifyer;
-            });
-        }
-    };
-
-    function delegateToCalls(method, matchAny, actual, notCalled) {
-        spyApi[method] = function () {
-            if (!this.called) {
-                if (notCalled) {
-                    return notCalled.apply(this, arguments);
-                }
-                return false;
-            }
-
-            var currentCall;
-            var matches = 0;
-
-            for (var i = 0, l = this.callCount; i < l; i += 1) {
-                currentCall = this.getCall(i);
-
-                if (currentCall[actual || method].apply(currentCall, arguments)) {
-                    matches += 1;
-
-                    if (matchAny) {
-                        return true;
-                    }
-                }
-            }
-
-            return matches === this.callCount;
-        };
-    }
-
-    delegateToCalls("calledOn", true);
-    delegateToCalls("alwaysCalledOn", false, "calledOn");
-    delegateToCalls("calledWith", true);
-    delegateToCalls("calledWithMatch", true);
-    delegateToCalls("alwaysCalledWith", false, "calledWith");
-    delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
-    delegateToCalls("calledWithExactly", true);
-    delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
-    delegateToCalls("neverCalledWith", false, "notCalledWith",
-        function () { return true; });
-    delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
-        function () { return true; });
-    delegateToCalls("threw", true);
-    delegateToCalls("alwaysThrew", false, "threw");
-    delegateToCalls("returned", true);
-    delegateToCalls("alwaysReturned", false, "returned");
-    delegateToCalls("calledWithNew", true);
-    delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
-    delegateToCalls("callArg", false, "callArgWith", function () {
-        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
-    });
-    spyApi.callArgWith = spyApi.callArg;
-    delegateToCalls("callArgOn", false, "callArgOnWith", function () {
-        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
-    });
-    spyApi.callArgOnWith = spyApi.callArgOn;
-    delegateToCalls("yield", false, "yield", function () {
-        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
-    });
-    // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
-    spyApi.invokeCallback = spyApi.yield;
-    delegateToCalls("yieldOn", false, "yieldOn", function () {
-        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
-    });
-    delegateToCalls("yieldTo", false, "yieldTo", function (property) {
-        throw new Error(this.toString() + " cannot yield to '" + property +
-            "' since it was not yet invoked.");
-    });
-    delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
-        throw new Error(this.toString() + " cannot yield to '" + property +
-            "' since it was not yet invoked.");
-    });
-
-    spyApi.formatters = {
-        "c": function (spy) {
-            return sinon.timesInWords(spy.callCount);
-        },
-
-        "n": function (spy) {
-            return spy.toString();
-        },
-
-        "C": function (spy) {
-            var calls = [];
-
-            for (var i = 0, l = spy.callCount; i < l; ++i) {
-                var stringifiedCall = "    " + spy.getCall(i).toString();
-                if (/\n/.test(calls[i - 1])) {
-                    stringifiedCall = "\n" + stringifiedCall;
-                }
-                push.call(calls, stringifiedCall);
-            }
-
-            return calls.length > 0 ? "\n" + calls.join("\n") : "";
-        },
-
-        "t": function (spy) {
-            var objects = [];
-
-            for (var i = 0, l = spy.callCount; i < l; ++i) {
-                push.call(objects, sinon.format(spy.thisValues[i]));
-            }
-
-            return objects.join(", ");
-        },
-
-        "*": function (spy, args) {
-            var formatted = [];
-
-            for (var i = 0, l = args.length; i < l; ++i) {
-                push.call(formatted, sinon.format(args[i]));
-            }
-
-            return formatted.join(", ");
-        }
-    };
-
-    sinon.extend(spy, spyApi);
-
-    spy.spyCall = sinon.spyCall;
-
-    if (commonJSModule) {
-        module.exports = spy;
-    } else {
-        sinon.spy = spy;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- */
-/*jslint eqeqeq: false, onevar: false*/
-/*global module, require, sinon, process, setImmediate, setTimeout*/
-/**
- * Stub behavior
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @author Tim Fischbach (mail@timfischbach.de)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    var slice = Array.prototype.slice;
-    var join = Array.prototype.join;
-    var proto;
-
-    var nextTick = (function () {
-        if (typeof process === "object" && typeof process.nextTick === "function") {
-            return process.nextTick;
-        } else if (typeof setImmediate === "function") {
-            return setImmediate;
-        } else {
-            return function (callback) {
-                setTimeout(callback, 0);
-            };
-        }
-    })();
-
-    function throwsException(error, message) {
-        if (typeof error == "string") {
-            this.exception = new Error(message || "");
-            this.exception.name = error;
-        } else if (!error) {
-            this.exception = new Error("Error");
-        } else {
-            this.exception = error;
-        }
-
-        return this;
-    }
-
-    function getCallback(behavior, args) {
-        var callArgAt = behavior.callArgAt;
-
-        if (callArgAt < 0) {
-            var callArgProp = behavior.callArgProp;
-
-            for (var i = 0, l = args.length; i < l; ++i) {
-                if (!callArgProp && typeof args[i] == "function") {
-                    return args[i];
-                }
-
-                if (callArgProp && args[i] &&
-                    typeof args[i][callArgProp] == "function") {
-                    return args[i][callArgProp];
-                }
-            }
-
-            return null;
-        }
-
-        return args[callArgAt];
-    }
-
-    function getCallbackError(behavior, func, args) {
-        if (behavior.callArgAt < 0) {
-            var msg;
-
-            if (behavior.callArgProp) {
-                msg = sinon.functionName(behavior.stub) +
-                    " expected to yield to '" + behavior.callArgProp +
-                    "', but no object with such a property was passed.";
-            } else {
-                msg = sinon.functionName(behavior.stub) +
-                    " expected to yield, but no callback was passed.";
-            }
-
-            if (args.length > 0) {
-                msg += " Received [" + join.call(args, ", ") + "]";
-            }
-
-            return msg;
-        }
-
-        return "argument at index " + behavior.callArgAt + " is not a function: " + func;
-    }
-
-    function callCallback(behavior, args) {
-        if (typeof behavior.callArgAt == "number") {
-            var func = getCallback(behavior, args);
-
-            if (typeof func != "function") {
-                throw new TypeError(getCallbackError(behavior, func, args));
-            }
-
-            if (behavior.callbackAsync) {
-                nextTick(function() {
-                    func.apply(behavior.callbackContext, behavior.callbackArguments);
-                });
-            } else {
-                func.apply(behavior.callbackContext, behavior.callbackArguments);
-            }
-        }
-    }
-
-    proto = {
-        create: function(stub) {
-            var behavior = sinon.extend({}, sinon.behavior);
-            delete behavior.create;
-            behavior.stub = stub;
-
-            return behavior;
-        },
-
-        isPresent: function() {
-            return (typeof this.callArgAt == 'number' ||
-                    this.exception ||
-                    typeof this.returnArgAt == 'number' ||
-                    this.returnThis ||
-                    this.returnValueDefined);
-        },
-
-        invoke: function(context, args) {
-            callCallback(this, args);
-
-            if (this.exception) {
-                throw this.exception;
-            } else if (typeof this.returnArgAt == 'number') {
-                return args[this.returnArgAt];
-            } else if (this.returnThis) {
-                return context;
-            }
-
-            return this.returnValue;
-        },
-
-        onCall: function(index) {
-            return this.stub.onCall(index);
-        },
-
-        onFirstCall: function() {
-            return this.stub.onFirstCall();
-        },
-
-        onSecondCall: function() {
-            return this.stub.onSecondCall();
-        },
-
-        onThirdCall: function() {
-            return this.stub.onThirdCall();
-        },
-
-        withArgs: function(/* arguments */) {
-            throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
-                            'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
-        },
-
-        callsArg: function callsArg(pos) {
-            if (typeof pos != "number") {
-                throw new TypeError("argument index is not number");
-            }
-
-            this.callArgAt = pos;
-            this.callbackArguments = [];
-            this.callbackContext = undefined;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        callsArgOn: function callsArgOn(pos, context) {
-            if (typeof pos != "number") {
-                throw new TypeError("argument index is not number");
-            }
-            if (typeof context != "object") {
-                throw new TypeError("argument context is not an object");
-            }
-
-            this.callArgAt = pos;
-            this.callbackArguments = [];
-            this.callbackContext = context;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        callsArgWith: function callsArgWith(pos) {
-            if (typeof pos != "number") {
-                throw new TypeError("argument index is not number");
-            }
-
-            this.callArgAt = pos;
-            this.callbackArguments = slice.call(arguments, 1);
-            this.callbackContext = undefined;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        callsArgOnWith: function callsArgWith(pos, context) {
-            if (typeof pos != "number") {
-                throw new TypeError("argument index is not number");
-            }
-            if (typeof context != "object") {
-                throw new TypeError("argument context is not an object");
-            }
-
-            this.callArgAt = pos;
-            this.callbackArguments = slice.call(arguments, 2);
-            this.callbackContext = context;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        yields: function () {
-            this.callArgAt = -1;
-            this.callbackArguments = slice.call(arguments, 0);
-            this.callbackContext = undefined;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        yieldsOn: function (context) {
-            if (typeof context != "object") {
-                throw new TypeError("argument context is not an object");
-            }
-
-            this.callArgAt = -1;
-            this.callbackArguments = slice.call(arguments, 1);
-            this.callbackContext = context;
-            this.callArgProp = undefined;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        yieldsTo: function (prop) {
-            this.callArgAt = -1;
-            this.callbackArguments = slice.call(arguments, 1);
-            this.callbackContext = undefined;
-            this.callArgProp = prop;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-        yieldsToOn: function (prop, context) {
-            if (typeof context != "object") {
-                throw new TypeError("argument context is not an object");
-            }
-
-            this.callArgAt = -1;
-            this.callbackArguments = slice.call(arguments, 2);
-            this.callbackContext = context;
-            this.callArgProp = prop;
-            this.callbackAsync = false;
-
-            return this;
-        },
-
-
-        "throws": throwsException,
-        throwsException: throwsException,
-
-        returns: function returns(value) {
-            this.returnValue = value;
-            this.returnValueDefined = true;
-
-            return this;
-        },
-
-        returnsArg: function returnsArg(pos) {
-            if (typeof pos != "number") {
-                throw new TypeError("argument index is not number");
-            }
-
-            this.returnArgAt = pos;
-
-            return this;
-        },
-
-        returnsThis: function returnsThis() {
-            this.returnThis = true;
-
-            return this;
-        }
-    };
-
-    // create asynchronous versions of callsArg* and yields* methods
-    for (var method in proto) {
-        // need to avoid creating anotherasync versions of the newly added async methods
-        if (proto.hasOwnProperty(method) &&
-            method.match(/^(callsArg|yields)/) &&
-            !method.match(/Async/)) {
-            proto[method + 'Async'] = (function (syncFnName) {
-                return function () {
-                    var result = this[syncFnName].apply(this, arguments);
-                    this.callbackAsync = true;
-                    return result;
-                };
-            })(method);
-        }
-    }
-
-    if (commonJSModule) {
-        module.exports = proto;
-    } else {
-        sinon.behavior = proto;
-    }
-}(typeof sinon == "object" && sinon || null));
-/**
- * @depend ../sinon.js
- * @depend spy.js
- * @depend behavior.js
- */
-/*jslint eqeqeq: false, onevar: false*/
-/*global module, require, sinon*/
-/**
- * Stub functions
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function stub(object, property, func) {
-        if (!!func && typeof func != "function") {
-            throw new TypeError("Custom stub should be function");
-        }
-
-        var wrapper;
-
-        if (func) {
-            wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
-        } else {
-            wrapper = stub.create();
-        }
-
-        if (!object && typeof property === "undefined") {
-            return sinon.stub.create();
-        }
-
-        if (typeof property === "undefined" && typeof object == "object") {
-            for (var prop in object) {
-                if (typeof object[prop] === "function") {
-                    stub(object, prop);
-                }
-            }
-
-            return object;
-        }
-
-        return sinon.wrapMethod(object, property, wrapper);
-    }
-
-    function getDefaultBehavior(stub) {
-        return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
-    }
-
-    function getParentBehaviour(stub) {
-        return (stub.parent && getCurrentBehavior(stub.parent));
-    }
-
-    function getCurrentBehavior(stub) {
-        var behavior = stub.behaviors[stub.callCount - 1];
-        return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
-    }
-
-    var uuid = 0;
-
-    sinon.extend(stub, (function () {
-        var proto = {
-            create: function create() {
-                var functionStub = function () {
-                    return getCurrentBehavior(functionStub).invoke(this, arguments);
-                };
-
-                functionStub.id = "stub#" + uuid++;
-                var orig = functionStub;
-                functionStub = sinon.spy.create(functionStub);
-                functionStub.func = orig;
-
-                sinon.extend(functionStub, stub);
-                functionStub._create = sinon.stub.create;
-                functionStub.displayName = "stub";
-                functionStub.toString = sinon.functionToString;
-
-                functionStub.defaultBehavior = null;
-                functionStub.behaviors = [];
-
-                return functionStub;
-            },
-
-            resetBehavior: function () {
-                var i;
-
-                this.defaultBehavior = null;
-                this.behaviors = [];
-
-                delete this.returnValue;
-                delete this.returnArgAt;
-                this.returnThis = false;
-
-                if (this.fakes) {
-                    for (i = 0; i < this.fakes.length; i++) {
-                        this.fakes[i].resetBehavior();
-                    }
-                }
-            },
-
-            onCall: function(index) {
-                if (!this.behaviors[index]) {
-                    this.behaviors[index] = sinon.behavior.create(this);
-                }
-
-                return this.behaviors[index];
-            },
-
-            onFirstCall: function() {
-                return this.onCall(0);
-            },
-
-            onSecondCall: function() {
-                return this.onCall(1);
-            },
-
-            onThirdCall: function() {
-                return this.onCall(2);
-            }
-        };
-
-        for (var method in sinon.behavior) {
-            if (sinon.behavior.hasOwnProperty(method) &&
-                !proto.hasOwnProperty(method) &&
-                method != 'create' &&
-                method != 'withArgs' &&
-                method != 'invoke') {
-                proto[method] = (function(behaviorMethod) {
-                    return function() {
-                        this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
-                        this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
-                        return this;
-                    };
-                }(method));
-            }
-        }
-
-        return proto;
-    }()));
-
-    if (commonJSModule) {
-        module.exports = stub;
-    } else {
-        sinon.stub = stub;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- */
-/*jslint eqeqeq: false, onevar: false, nomen: false*/
-/*global module, require, sinon*/
-/**
- * Mock functions.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-    var push = [].push;
-    var match;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    match = sinon.match;
-
-    if (!match && commonJSModule) {
-        match = require("./match");
-    }
-
-    function mock(object) {
-        if (!object) {
-            return sinon.expectation.create("Anonymous mock");
-        }
-
-        return mock.create(object);
-    }
-
-    sinon.mock = mock;
-
-    sinon.extend(mock, (function () {
-        function each(collection, callback) {
-            if (!collection) {
-                return;
-            }
-
-            for (var i = 0, l = collection.length; i < l; i += 1) {
-                callback(collection[i]);
-            }
-        }
-
-        return {
-            create: function create(object) {
-                if (!object) {
-                    throw new TypeError("object is null");
-                }
-
-                var mockObject = sinon.extend({}, mock);
-                mockObject.object = object;
-                delete mockObject.create;
-
-                return mockObject;
-            },
-
-            expects: function expects(method) {
-                if (!method) {
-                    throw new TypeError("method is falsy");
-                }
-
-                if (!this.expectations) {
-                    this.expectations = {};
-                    this.proxies = [];
-                }
-
-                if (!this.expectations[method]) {
-                    this.expectations[method] = [];
-                    var mockObject = this;
-
-                    sinon.wrapMethod(this.object, method, function () {
-                        return mockObject.invokeMethod(method, this, arguments);
-                    });
-
-                    push.call(this.proxies, method);
-                }
-
-                var expectation = sinon.expectation.create(method);
-                push.call(this.expectations[method], expectation);
-
-                return expectation;
-            },
-
-            restore: function restore() {
-                var object = this.object;
-
-                each(this.proxies, function (proxy) {
-                    if (typeof object[proxy].restore == "function") {
-                        object[proxy].restore();
-                    }
-                });
-            },
-
-            verify: function verify() {
-                var expectations = this.expectations || {};
-                var messages = [], met = [];
-
-                each(this.proxies, function (proxy) {
-                    each(expectations[proxy], function (expectation) {
-                        if (!expectation.met()) {
-                            push.call(messages, expectation.toString());
-                        } else {
-                            push.call(met, expectation.toString());
-                        }
-                    });
-                });
-
-                this.restore();
-
-                if (messages.length > 0) {
-                    sinon.expectation.fail(messages.concat(met).join("\n"));
-                } else {
-                    sinon.expectation.pass(messages.concat(met).join("\n"));
-                }
-
-                return true;
-            },
-
-            invokeMethod: function invokeMethod(method, thisValue, args) {
-                var expectations = this.expectations && this.expectations[method];
-                var length = expectations && expectations.length || 0, i;
-
-                for (i = 0; i < length; i += 1) {
-                    if (!expectations[i].met() &&
-                        expectations[i].allowsCall(thisValue, args)) {
-                        return expectations[i].apply(thisValue, args);
-                    }
-                }
-
-                var messages = [], available, exhausted = 0;
-
-                for (i = 0; i < length; i += 1) {
-                    if (expectations[i].allowsCall(thisValue, args)) {
-                        available = available || expectations[i];
-                    } else {
-                        exhausted += 1;
-                    }
-                    push.call(messages, "    " + expectations[i].toString());
-                }
-
-                if (exhausted === 0) {
-                    return available.apply(thisValue, args);
-                }
-
-                messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
-                    proxy: method,
-                    args: args
-                }));
-
-                sinon.expectation.fail(messages.join("\n"));
-            }
-        };
-    }()));
-
-    var times = sinon.timesInWords;
-
-    sinon.expectation = (function () {
-        var slice = Array.prototype.slice;
-        var _invoke = sinon.spy.invoke;
-
-        function callCountInWords(callCount) {
-            if (callCount == 0) {
-                return "never called";
-            } else {
-                return "called " + times(callCount);
-            }
-        }
-
-        function expectedCallCountInWords(expectation) {
-            var min = expectation.minCalls;
-            var max = expectation.maxCalls;
-
-            if (typeof min == "number" && typeof max == "number") {
-                var str = times(min);
-
-                if (min != max) {
-                    str = "at least " + str + " and at most " + times(max);
-                }
-
-                return str;
-            }
-
-            if (typeof min == "number") {
-                return "at least " + times(min);
-            }
-
-            return "at most " + times(max);
-        }
-
-        function receivedMinCalls(expectation) {
-            var hasMinLimit = typeof expectation.minCalls == "number";
-            return !hasMinLimit || expectation.callCount >= expectation.minCalls;
-        }
-
-        function receivedMaxCalls(expectation) {
-            if (typeof expectation.maxCalls != "number") {
-                return false;
-            }
-
-            return expectation.callCount == expectation.maxCalls;
-        }
-
-        function verifyMatcher(possibleMatcher, arg){
-            if (match && match.isMatcher(possibleMatcher)) {
-                return possibleMatcher.test(arg);
-            } else {
-                return true;
-            }
-        }
-
-        return {
-            minCalls: 1,
-            maxCalls: 1,
-
-            create: function create(methodName) {
-                var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
-                delete expectation.create;
-                expectation.method = methodName;
-
-                return expectation;
-            },
-
-            invoke: function invoke(func, thisValue, args) {
-                this.verifyCallAllowed(thisValue, args);
-
-                return _invoke.apply(this, arguments);
-            },
-
-            atLeast: function atLeast(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not number");
-                }
-
-                if (!this.limitsSet) {
-                    this.maxCalls = null;
-                    this.limitsSet = true;
-                }
-
-                this.minCalls = num;
-
-                return this;
-            },
-
-            atMost: function atMost(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not number");
-                }
-
-                if (!this.limitsSet) {
-                    this.minCalls = null;
-                    this.limitsSet = true;
-                }
-
-                this.maxCalls = num;
-
-                return this;
-            },
-
-            never: function never() {
-                return this.exactly(0);
-            },
-
-            once: function once() {
-                return this.exactly(1);
-            },
-
-            twice: function twice() {
-                return this.exactly(2);
-            },
-
-            thrice: function thrice() {
-                return this.exactly(3);
-            },
-
-            exactly: function exactly(num) {
-                if (typeof num != "number") {
-                    throw new TypeError("'" + num + "' is not a number");
-                }
-
-                this.atLeast(num);
-                return this.atMost(num);
-            },
-
-            met: function met() {
-                return !this.failed && receivedMinCalls(this);
-            },
-
-            verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
-                if (receivedMaxCalls(this)) {
-                    this.failed = true;
-                    sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
-                }
-
-                if ("expectedThis" in this && this.expectedThis !== thisValue) {
-                    sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
-                        this.expectedThis);
-                }
-
-                if (!("expectedArguments" in this)) {
-                    return;
-                }
-
-                if (!args) {
-                    sinon.expectation.fail(this.method + " received no arguments, expected " +
-                        sinon.format(this.expectedArguments));
-                }
-
-                if (args.length < this.expectedArguments.length) {
-                    sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
-                        "), expected " + sinon.format(this.expectedArguments));
-                }
-
-                if (this.expectsExactArgCount &&
-                    args.length != this.expectedArguments.length) {
-                    sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
-                        "), expected " + sinon.format(this.expectedArguments));
-                }
-
-                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
-
-                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
-                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
-                            ", didn't match " + this.expectedArguments.toString());
-                    }
-
-                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
-                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
-                            ", expected " + sinon.format(this.expectedArguments));
-                    }
-                }
-            },
-
-            allowsCall: function allowsCall(thisValue, args) {
-                if (this.met() && receivedMaxCalls(this)) {
-                    return false;
-                }
-
-                if ("expectedThis" in this && this.expectedThis !== thisValue) {
-                    return false;
-                }
-
-                if (!("expectedArguments" in this)) {
-                    return true;
-                }
-
-                args = args || [];
-
-                if (args.length < this.expectedArguments.length) {
-                    return false;
-                }
-
-                if (this.expectsExactArgCount &&
-                    args.length != this.expectedArguments.length) {
-                    return false;
-                }
-
-                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
-                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
-                        return false;
-                    }
-
-                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
-                        return false;
-                    }
-                }
-
-                return true;
-            },
-
-            withArgs: function withArgs() {
-                this.expectedArguments = slice.call(arguments);
-                return this;
-            },
-
-            withExactArgs: function withExactArgs() {
-                this.withArgs.apply(this, arguments);
-                this.expectsExactArgCount = true;
-                return this;
-            },
-
-            on: function on(thisValue) {
-                this.expectedThis = thisValue;
-                return this;
-            },
-
-            toString: function () {
-                var args = (this.expectedArguments || []).slice();
-
-                if (!this.expectsExactArgCount) {
-                    push.call(args, "[...]");
-                }
-
-                var callStr = sinon.spyCall.toString.call({
-                    proxy: this.method || "anonymous mock expectation",
-                    args: args
-                });
-
-                var message = callStr.replace(", [...", "[, ...") + " " +
-                    expectedCallCountInWords(this);
-
-                if (this.met()) {
-                    return "Expectation met: " + message;
-                }
-
-                return "Expected " + message + " (" +
-                    callCountInWords(this.callCount) + ")";
-            },
-
-            verify: function verify() {
-                if (!this.met()) {
-                    sinon.expectation.fail(this.toString());
-                } else {
-                    sinon.expectation.pass(this.toString());
-                }
-
-                return true;
-            },
-
-            pass: function(message) {
-              sinon.assert.pass(message);
-            },
-            fail: function (message) {
-                var exception = new Error(message);
-                exception.name = "ExpectationError";
-
-                throw exception;
-            }
-        };
-    }());
-
-    if (commonJSModule) {
-        module.exports = mock;
-    } else {
-        sinon.mock = mock;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- * @depend mock.js
- */
-/*jslint eqeqeq: false, onevar: false, forin: true*/
-/*global module, require, sinon*/
-/**
- * Collections of stubs, spies and mocks.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-    var push = [].push;
-    var hasOwnProperty = Object.prototype.hasOwnProperty;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function getFakes(fakeCollection) {
-        if (!fakeCollection.fakes) {
-            fakeCollection.fakes = [];
-        }
-
-        return fakeCollection.fakes;
-    }
-
-    function each(fakeCollection, method) {
-        var fakes = getFakes(fakeCollection);
-
-        for (var i = 0, l = fakes.length; i < l; i += 1) {
-            if (typeof fakes[i][method] == "function") {
-                fakes[i][method]();
-            }
-        }
-    }
-
-    function compact(fakeCollection) {
-        var fakes = getFakes(fakeCollection);
-        var i = 0;
-        while (i < fakes.length) {
-          fakes.splice(i, 1);
-        }
-    }
-
-    var collection = {
-        verify: function resolve() {
-            each(this, "verify");
-        },
-
-        restore: function restore() {
-            each(this, "restore");
-            compact(this);
-        },
-
-        verifyAndRestore: function verifyAndRestore() {
-            var exception;
-
-            try {
-                this.verify();
-            } catch (e) {
-                exception = e;
-            }
-
-            this.restore();
-
-            if (exception) {
-                throw exception;
-            }
-        },
-
-        add: function add(fake) {
-            push.call(getFakes(this), fake);
-            return fake;
-        },
-
-        spy: function spy() {
-            return this.add(sinon.spy.apply(sinon, arguments));
-        },
-
-        stub: function stub(object, property, value) {
-            if (property) {
-                var original = object[property];
-
-                if (typeof original != "function") {
-                    if (!hasOwnProperty.call(object, property)) {
-                        throw new TypeError("Cannot stub non-existent own property " + property);
-                    }
-
-                    object[property] = value;
-
-                    return this.add({
-                        restore: function () {
-                            object[property] = original;
-                        }
-                    });
-                }
-            }
-            if (!property && !!object && typeof object == "object") {
-                var stubbedObj = sinon.stub.apply(sinon, arguments);
-
-                for (var prop in stubbedObj) {
-                    if (typeof stubbedObj[prop] === "function") {
-                        this.add(stubbedObj[prop]);
-                    }
-                }
-
-                return stubbedObj;
-            }
-
-            return this.add(sinon.stub.apply(sinon, arguments));
-        },
-
-        mock: function mock() {
-            return this.add(sinon.mock.apply(sinon, arguments));
-        },
-
-        inject: function inject(obj) {
-            var col = this;
-
-            obj.spy = function () {
-                return col.spy.apply(col, arguments);
-            };
-
-            obj.stub = function () {
-                return col.stub.apply(col, arguments);
-            };
-
-            obj.mock = function () {
-                return col.mock.apply(col, arguments);
-            };
-
-            return obj;
-        }
-    };
-
-    if (commonJSModule) {
-        module.exports = collection;
-    } else {
-        sinon.collection = collection;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
-/*global module, require, window*/
-/**
- * Fake timer API
- * setTimeout
- * setInterval
- * clearTimeout
- * clearInterval
- * tick
- * reset
- * Date
- *
- * Inspired by jsUnitMockTimeOut from JsUnit
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    var sinon = {};
-}
-
-(function (global) {
-    var id = 1;
-
-    function addTimer(args, recurring) {
-        if (args.length === 0) {
-            throw new Error("Function requires at least 1 parameter");
-        }
-
-        if (typeof args[0] === "undefined") {
-            throw new Error("Callback must be provided to timer calls");
-        }
-
-        var toId = id++;
-        var delay = args[1] || 0;
-
-        if (!this.timeouts) {
-            this.timeouts = {};
-        }
-
-        this.timeouts[toId] = {
-            id: toId,
-            func: args[0],
-            callAt: this.now + delay,
-            invokeArgs: Array.prototype.slice.call(args, 2)
-        };
-
-        if (recurring === true) {
-            this.timeouts[toId].interval = delay;
-        }
-
-        return toId;
-    }
-
-    function parseTime(str) {
-        if (!str) {
-            return 0;
-        }
-
-        var strings = str.split(":");
-        var l = strings.length, i = l;
-        var ms = 0, parsed;
-
-        if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
-            throw new Error("tick only understands numbers and 'h:m:s'");
-        }
-
-        while (i--) {
-            parsed = parseInt(strings[i], 10);
-
-            if (parsed >= 60) {
-                throw new Error("Invalid time " + str);
-            }
-
-            ms += parsed * Math.pow(60, (l - i - 1));
-        }
-
-        return ms * 1000;
-    }
-
-    function createObject(object) {
-        var newObject;
-
-        if (Object.create) {
-            newObject = Object.create(object);
-        } else {
-            var F = function () {};
-            F.prototype = object;
-            newObject = new F();
-        }
-
-        newObject.Date.clock = newObject;
-        return newObject;
-    }
-
-    sinon.clock = {
-        now: 0,
-
-        create: function create(now) {
-            var clock = createObject(this);
-
-            if (typeof now == "number") {
-                clock.now = now;
-            }
-
-            if (!!now && typeof now == "object") {
-                throw new TypeError("now should be milliseconds since UNIX epoch");
-            }
-
-            return clock;
-        },
-
-        setTimeout: function setTimeout(callback, timeout) {
-            return addTimer.call(this, arguments, false);
-        },
-
-        clearTimeout: function clearTimeout(timerId) {
-            if (!this.timeouts) {
-                this.timeouts = [];
-            }
-
-            if (timerId in this.timeouts) {
-                delete this.timeouts[timerId];
-            }
-        },
-
-        setInterval: function setInterval(callback, timeout) {
-            return addTimer.call(this, arguments, true);
-        },
-
-        clearInterval: function clearInterval(timerId) {
-            this.clearTimeout(timerId);
-        },
-
-        setImmediate: function setImmediate(callback) {
-            var passThruArgs = Array.prototype.slice.call(arguments, 1);
-
-            return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
-        },
-
-        clearImmediate: function clearImmediate(timerId) {
-            this.clearTimeout(timerId);
-        },
-
-        tick: function tick(ms) {
-            ms = typeof ms == "number" ? ms : parseTime(ms);
-            var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
-            var timer = this.firstTimerInRange(tickFrom, tickTo);
-
-            var firstException;
-            while (timer && tickFrom <= tickTo) {
-                if (this.timeouts[timer.id]) {
-                    tickFrom = this.now = timer.callAt;
-                    try {
-                      this.callTimer(timer);
-                    } catch (e) {
-                      firstException = firstException || e;
-                    }
-                }
-
-                timer = this.firstTimerInRange(previous, tickTo);
-                previous = tickFrom;
-            }
-
-            this.now = tickTo;
-
-            if (firstException) {
-              throw firstException;
-            }
-
-            return this.now;
-        },
-
-        firstTimerInRange: function (from, to) {
-            var timer, smallest = null, originalTimer;
-
-            for (var id in this.timeouts) {
-                if (this.timeouts.hasOwnProperty(id)) {
-                    if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
-                        continue;
-                    }
-
-                    if (smallest === null || this.timeouts[id].callAt < smallest) {
-                        originalTimer = this.timeouts[id];
-                        smallest = this.timeouts[id].callAt;
-
-                        timer = {
-                            func: this.timeouts[id].func,
-                            callAt: this.timeouts[id].callAt,
-                            interval: this.timeouts[id].interval,
-                            id: this.timeouts[id].id,
-                            invokeArgs: this.timeouts[id].invokeArgs
-                        };
-                    }
-                }
-            }
-
-            return timer || null;
-        },
-
-        callTimer: function (timer) {
-            if (typeof timer.interval == "number") {
-                this.timeouts[timer.id].callAt += timer.interval;
-            } else {
-                delete this.timeouts[timer.id];
-            }
-
-            try {
-                if (typeof timer.func == "function") {
-                    timer.func.apply(null, timer.invokeArgs);
-                } else {
-                    eval(timer.func);
-                }
-            } catch (e) {
-              var exception = e;
-            }
-
-            if (!this.timeouts[timer.id]) {
-                if (exception) {
-                  throw exception;
-                }
-                return;
-            }
-
-            if (exception) {
-              throw exception;
-            }
-        },
-
-        reset: function reset() {
-            this.timeouts = {};
-        },
-
-        Date: (function () {
-            var NativeDate = Date;
-
-            function ClockDate(year, month, date, hour, minute, second, ms) {
-                // Defensive and verbose to avoid potential harm in passing
-                // explicit undefined when user does not pass argument
-                switch (arguments.length) {
-                case 0:
-                    return new NativeDate(ClockDate.clock.now);
-                case 1:
-                    return new NativeDate(year);
-                case 2:
-                    return new NativeDate(year, month);
-                case 3:
-                    return new NativeDate(year, month, date);
-                case 4:
-                    return new NativeDate(year, month, date, hour);
-                case 5:
-                    return new NativeDate(year, month, date, hour, minute);
-                case 6:
-                    return new NativeDate(year, month, date, hour, minute, second);
-                default:
-                    return new NativeDate(year, month, date, hour, minute, second, ms);
-                }
-            }
-
-            return mirrorDateProperties(ClockDate, NativeDate);
-        }())
-    };
-
-    function mirrorDateProperties(target, source) {
-        if (source.now) {
-            target.now = function now() {
-                return target.clock.now;
-            };
-        } else {
-            delete target.now;
-        }
-
-        if (source.toSource) {
-            target.toSource = function toSource() {
-                return source.toSource();
-            };
-        } else {
-            delete target.toSource;
-        }
-
-        target.toString = function toString() {
-            return source.toString();
-        };
-
-        target.prototype = source.prototype;
-        target.parse = source.parse;
-        target.UTC = source.UTC;
-        target.prototype.toUTCString = source.prototype.toUTCString;
-
-        for (var prop in source) {
-            if (source.hasOwnProperty(prop)) {
-                target[prop] = source[prop];
-            }
-        }
-
-        return target;
-    }
-
-    var methods = ["Date", "setTimeout", "setInterval",
-                   "clearTimeout", "clearInterval"];
-
-    if (typeof global.setImmediate !== "undefined") {
-        methods.push("setImmediate");
-    }
-
-    if (typeof global.clearImmediate !== "undefined") {
-        methods.push("clearImmediate");
-    }
-
-    function restore() {
-        var method;
-
-        for (var i = 0, l = this.methods.length; i < l; i++) {
-            method = this.methods[i];
-
-            if (global[method].hadOwnProperty) {
-                global[method] = this["_" + method];
-            } else {
-                try {
-                    delete global[method];
-                } catch (e) {}
-            }
-        }
-
-        // Prevent multiple executions which will completely remove these props
-        this.methods = [];
-    }
-
-    function stubGlobal(method, clock) {
-        clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
-        clock["_" + method] = global[method];
-
-        if (method == "Date") {
-            var date = mirrorDateProperties(clock[method], global[method]);
-            global[method] = date;
-        } else {
-            global[method] = function () {
-                return clock[method].apply(clock, arguments);
-            };
-
-            for (var prop in clock[method]) {
-                if (clock[method].hasOwnProperty(prop)) {
-                    global[method][prop] = clock[method][prop];
-                }
-            }
-        }
-
-        global[method].clock = clock;
-    }
-
-    sinon.useFakeTimers = function useFakeTimers(now) {
-        var clock = sinon.clock.create(now);
-        clock.restore = restore;
-        clock.methods = Array.prototype.slice.call(arguments,
-                                                   typeof now == "number" ? 1 : 0);
-
-        if (clock.methods.length === 0) {
-            clock.methods = methods;
-        }
-
-        for (var i = 0, l = clock.methods.length; i < l; i++) {
-            stubGlobal(clock.methods[i], clock);
-        }
-
-        return clock;
-    };
-}(typeof global != "undefined" && typeof global !== "function" ? global : this));
-
-sinon.timers = {
-    setTimeout: setTimeout,
-    clearTimeout: clearTimeout,
-    setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
-    clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
-    setInterval: setInterval,
-    clearInterval: clearInterval,
-    Date: Date
-};
-
-if (typeof module !== 'undefined' && module.exports) {
-    module.exports = sinon;
-}
-
-/*jslint eqeqeq: false, onevar: false*/
-/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
-/**
- * Minimal Event interface implementation
- *
- * Original implementation by Sven Fuchs: https://gist.github.com/995028
- * Modifications and tests by Christian Johansen.
- *
- * @author Sven Fuchs (svenfuchs@artweb-design.de)
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2011 Sven Fuchs, Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    this.sinon = {};
-}
-
-(function () {
-    var push = [].push;
-
-    sinon.Event = function Event(type, bubbles, cancelable, target) {
-        this.initEvent(type, bubbles, cancelable, target);
-    };
-
-    sinon.Event.prototype = {
-        initEvent: function(type, bubbles, cancelable, target) {
-            this.type = type;
-            this.bubbles = bubbles;
-            this.cancelable = cancelable;
-            this.target = target;
-        },
-
-        stopPropagation: function () {},
-
-        preventDefault: function () {
-            this.defaultPrevented = true;
-        }
-    };
-
-    sinon.EventTarget = {
-        addEventListener: function addEventListener(event, listener) {
-            this.eventListeners = this.eventListeners || {};
-            this.eventListeners[event] = this.eventListeners[event] || [];
-            push.call(this.eventListeners[event], listener);
-        },
-
-        removeEventListener: function removeEventListener(event, listener) {
-            var listeners = this.eventListeners && this.eventListeners[event] || [];
-
-            for (var i = 0, l = listeners.length; i < l; ++i) {
-                if (listeners[i] == listener) {
-                    return listeners.splice(i, 1);
-                }
-            }
-        },
-
-        dispatchEvent: function dispatchEvent(event) {
-            var type = event.type;
-            var listeners = this.eventListeners && this.eventListeners[type] || [];
-
-            for (var i = 0; i < listeners.length; i++) {
-                if (typeof listeners[i] == "function") {
-                    listeners[i].call(this, event);
-                } else {
-                    listeners[i].handleEvent(event);
-                }
-            }
-
-            return !!event.defaultPrevented;
-        }
-    };
-}());
-
-/**
- * @depend ../../sinon.js
- * @depend event.js
- */
-/*jslint eqeqeq: false, onevar: false*/
-/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
-/**
- * Fake XMLHttpRequest object
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-// wrapper for global
-(function(global) {
-
-    if (typeof sinon === "undefined") {
-        global.sinon = {};
-    }
-    sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
-
-    var xhr = sinon.xhr;
-    xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
-    xhr.GlobalActiveXObject = global.ActiveXObject;
-    xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
-    xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
-    xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
-                                     ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
-    xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
-
-    /*jsl:ignore*/
-    var unsafeHeaders = {
-        "Accept-Charset": true,
-        "Accept-Encoding": true,
-        "Connection": true,
-        "Content-Length": true,
-        "Cookie": true,
-        "Cookie2": true,
-        "Content-Transfer-Encoding": true,
-        "Date": true,
-        "Expect": true,
-        "Host": true,
-        "Keep-Alive": true,
-        "Referer": true,
-        "TE": true,
-        "Trailer": true,
-        "Transfer-Encoding": true,
-        "Upgrade": true,
-        "User-Agent": true,
-        "Via": true
-    };
-    /*jsl:end*/
-
-    function FakeXMLHttpRequest() {
-        this.readyState = FakeXMLHttpRequest.UNSENT;
-        this.requestHeaders = {};
-        this.requestBody = null;
-        this.status = 0;
-        this.statusText = "";
-        this.upload = new UploadProgress();
-        if (sinon.xhr.supportsCORS) {
-            this.withCredentials = false;
-        }
-
-
-        var xhr = this;
-        var events = ["loadstart", "load", "abort", "loadend"];
-
-        function addEventListener(eventName) {
-            xhr.addEventListener(eventName, function (event) {
-                var listener = xhr["on" + eventName];
-
-                if (listener && typeof listener == "function") {
-                    listener(event);
-                }
-            });
-        }
-
-        for (var i = events.length - 1; i >= 0; i--) {
-            addEventListener(events[i]);
-        }
-
-        if (typeof FakeXMLHttpRequest.onCreate == "function") {
-            FakeXMLHttpRequest.onCreate(this);
-        }
-    }
-
-    // An upload object is created for each
-    // FakeXMLHttpRequest and allows upload
-    // events to be simulated using uploadProgress
-    // and uploadError.
-    function UploadProgress() {
-        this.eventListeners = {
-            "progress": [],
-            "load": [],
-            "abort": [],
-            "error": []
-        }
-    }
-
-    UploadProgress.prototype.addEventListener = function(event, listener) {
-        this.eventListeners[event].push(listener);
-    };
-
-    UploadProgress.prototype.removeEventListener = function(event, listener) {
-        var listeners = this.eventListeners[event] || [];
-
-        for (var i = 0, l = listeners.length; i < l; ++i) {
-            if (listeners[i] == listener) {
-                return listeners.splice(i, 1);
-            }
-        }
-    };
-
-    UploadProgress.prototype.dispatchEvent = function(event) {
-        var listeners = this.eventListeners[event.type] || [];
-
-        for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
-            listener(event);
-        }
-    };
-
-    function verifyState(xhr) {
-        if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
-            throw new Error("INVALID_STATE_ERR");
-        }
-
-        if (xhr.sendFlag) {
-            throw new Error("INVALID_STATE_ERR");
-        }
-    }
-
-    // filtering to enable a white-list version of Sinon FakeXhr,
-    // where whitelisted requests are passed through to real XHR
-    function each(collection, callback) {
-        if (!collection) return;
-        for (var i = 0, l = collection.length; i < l; i += 1) {
-            callback(collection[i]);
-        }
-    }
-    function some(collection, callback) {
-        for (var index = 0; index < collection.length; index++) {
-            if(callback(collection[index]) === true) return true;
-        }
-        return false;
-    }
-    // largest arity in XHR is 5 - XHR#open
-    var apply = function(obj,method,args) {
-        switch(args.length) {
-        case 0: return obj[method]();
-        case 1: return obj[method](args[0]);
-        case 2: return obj[method](args[0],args[1]);
-        case 3: return obj[method](args[0],args[1],args[2]);
-        case 4: return obj[method](args[0],args[1],args[2],args[3]);
-        case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
-        }
-    };
-
-    FakeXMLHttpRequest.filters = [];
-    FakeXMLHttpRequest.addFilter = function(fn) {
-        this.filters.push(fn)
-    };
-    var IE6Re = /MSIE 6/;
-    FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
-        var xhr = new sinon.xhr.workingXHR();
-        each(["open","setRequestHeader","send","abort","getResponseHeader",
-              "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
-             function(method) {
-                 fakeXhr[method] = function() {
-                   return apply(xhr,method,arguments);
-                 };
-             });
-
-        var copyAttrs = function(args) {
-            each(args, function(attr) {
-              try {
-                fakeXhr[attr] = xhr[attr]
-              } catch(e) {
-                if(!IE6Re.test(navigator.userAgent)) throw e;
-              }
-            });
-        };
-
-        var stateChange = function() {
-            fakeXhr.readyState = xhr.readyState;
-            if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                copyAttrs(["status","statusText"]);
-            }
-            if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
-                copyAttrs(["responseText"]);
-            }
-            if(xhr.readyState === FakeXMLHttpRequest.DONE) {
-                copyAttrs(["responseXML"]);
-            }
-            if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
-        };
-        if(xhr.addEventListener) {
-          for(var event in fakeXhr.eventListeners) {
-              if(fakeXhr.eventListeners.hasOwnProperty(event)) {
-                  each(fakeXhr.eventListeners[event],function(handler) {
-                      xhr.addEventListener(event, handler);
-                  });
-              }
-          }
-          xhr.addEventListener("readystatechange",stateChange);
-        } else {
-          xhr.onreadystatechange = stateChange;
-        }
-        apply(xhr,"open",xhrArgs);
-    };
-    FakeXMLHttpRequest.useFilters = false;
-
-    function verifyRequestSent(xhr) {
-        if (xhr.readyState == FakeXMLHttpRequest.DONE) {
-            throw new Error("Request done");
-        }
-    }
-
-    function verifyHeadersReceived(xhr) {
-        if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
-            throw new Error("No headers received");
-        }
-    }
-
-    function verifyResponseBodyType(body) {
-        if (typeof body != "string") {
-            var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
-                                 body + ", which is not a string.");
-            error.name = "InvalidBodyException";
-            throw error;
-        }
-    }
-
-    sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
-        async: true,
-
-        open: function open(method, url, async, username, password) {
-            this.method = method;
-            this.url = url;
-            this.async = typeof async == "boolean" ? async : true;
-            this.username = username;
-            this.password = password;
-            this.responseText = null;
-            this.responseXML = null;
-            this.requestHeaders = {};
-            this.sendFlag = false;
-            if(sinon.FakeXMLHttpRequest.useFilters === true) {
-                var xhrArgs = arguments;
-                var defake = some(FakeXMLHttpRequest.filters,function(filter) {
-                    return filter.apply(this,xhrArgs)
-                });
-                if (defake) {
-                  return sinon.FakeXMLHttpRequest.defake(this,arguments);
-                }
-            }
-            this.readyStateChange(FakeXMLHttpRequest.OPENED);
-        },
-
-        readyStateChange: function readyStateChange(state) {
-            this.readyState = state;
-
-            if (typeof this.onreadystatechange == "function") {
-                try {
-                    this.onreadystatechange();
-                } catch (e) {
-                    sinon.logError("Fake XHR onreadystatechange handler", e);
-                }
-            }
-
-            this.dispatchEvent(new sinon.Event("readystatechange"));
-
-            switch (this.readyState) {
-                case FakeXMLHttpRequest.DONE:
-                    this.dispatchEvent(new sinon.Event("load", false, false, this));
-                    this.dispatchEvent(new sinon.Event("loadend", false, false, this));
-                    this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
-                    this.upload.dispatchEvent(new ProgressEvent("progress", {loaded: 100, total: 100}));
-                    break;
-            }
-        },
-
-        setRequestHeader: function setRequestHeader(header, value) {
-            verifyState(this);
-
-            if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
-                throw new Error("Refused to set unsafe header \"" + header + "\"");
-            }
-
-            if (this.requestHeaders[header]) {
-                this.requestHeaders[header] += "," + value;
-            } else {
-                this.requestHeaders[header] = value;
-            }
-        },
-
-        // Helps testing
-        setResponseHeaders: function setResponseHeaders(headers) {
-            this.responseHeaders = {};
-
-            for (var header in headers) {
-                if (headers.hasOwnProperty(header)) {
-                    this.responseHeaders[header] = headers[header];
-                }
-            }
-
-            if (this.async) {
-                this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
-            } else {
-                this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
-            }
-        },
-
-        // Currently treats ALL data as a DOMString (i.e. no Document)
-        send: function send(data) {
-            verifyState(this);
-
-            if (!/^(get|head)$/i.test(this.method)) {
-                if (this.requestHeaders["Content-Type"]) {
-                    var value = this.requestHeaders["Content-Type"].split(";");
-                    this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
-                } else {
-                    this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
-                }
-
-                this.requestBody = data;
-            }
-
-            this.errorFlag = false;
-            this.sendFlag = this.async;
-            this.readyStateChange(FakeXMLHttpRequest.OPENED);
-
-            if (typeof this.onSend == "function") {
-                this.onSend(this);
-            }
-
-            this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
-        },
-
-        abort: function abort() {
-            this.aborted = true;
-            this.responseText = null;
-            this.errorFlag = true;
-            this.requestHeaders = {};
-
-            if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
-                this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
-                this.sendFlag = false;
-            }
-
-            this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
-
-            this.dispatchEvent(new sinon.Event("abort", false, false, this));
-
-            this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
-
-            if (typeof this.onerror === "function") {
-                this.onerror();
-            }
-        },
-
-        getResponseHeader: function getResponseHeader(header) {
-            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                return null;
-            }
-
-            if (/^Set-Cookie2?$/i.test(header)) {
-                return null;
-            }
-
-            header = header.toLowerCase();
-
-            for (var h in this.responseHeaders) {
-                if (h.toLowerCase() == header) {
-                    return this.responseHeaders[h];
-                }
-            }
-
-            return null;
-        },
-
-        getAllResponseHeaders: function getAllResponseHeaders() {
-            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
-                return "";
-            }
-
-            var headers = "";
-
-            for (var header in this.responseHeaders) {
-                if (this.responseHeaders.hasOwnProperty(header) &&
-                    !/^Set-Cookie2?$/i.test(header)) {
-                    headers += header + ": " + this.responseHeaders[header] + "\r\n";
-                }
-            }
-
-            return headers;
-        },
-
-        setResponseBody: function setResponseBody(body) {
-            verifyRequestSent(this);
-            verifyHeadersReceived(this);
-            verifyResponseBodyType(body);
-
-            var chunkSize = this.chunkSize || 10;
-            var index = 0;
-            this.responseText = "";
-
-            do {
-                if (this.async) {
-                    this.readyStateChange(FakeXMLHttpRequest.LOADING);
-                }
-
-                this.responseText += body.substring(index, index + chunkSize);
-                index += chunkSize;
-            } while (index < body.length);
-
-            var type = this.getResponseHeader("Content-Type");
-
-            if (this.responseText &&
-                (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
-                try {
-                    this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
-                } catch (e) {
-                    // Unable to parse XML - no biggie
-                }
-            }
-
-            if (this.async) {
-                this.readyStateChange(FakeXMLHttpRequest.DONE);
-            } else {
-                this.readyState = FakeXMLHttpRequest.DONE;
-            }
-        },
-
-        respond: function respond(status, headers, body) {
-            this.setResponseHeaders(headers || {});
-            this.status = typeof status == "number" ? status : 200;
-            this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
-            this.setResponseBody(body || "");
-        },
-
-        uploadProgress: function uploadProgress(progressEventRaw) {
-            this.upload.dispatchEvent(new ProgressEvent("progress", progressEventRaw));
-        },
-
-        uploadError: function uploadError(error) {
-            this.upload.dispatchEvent(new CustomEvent("error", {"detail": error}));
-        }
-    });
-
-    sinon.extend(FakeXMLHttpRequest, {
-        UNSENT: 0,
-        OPENED: 1,
-        HEADERS_RECEIVED: 2,
-        LOADING: 3,
-        DONE: 4
-    });
-
-    // Borrowed from JSpec
-    FakeXMLHttpRequest.parseXML = function parseXML(text) {
-        var xmlDoc;
-
-        if (typeof DOMParser != "undefined") {
-            var parser = new DOMParser();
-            xmlDoc = parser.parseFromString(text, "text/xml");
-        } else {
-            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
-            xmlDoc.async = "false";
-            xmlDoc.loadXML(text);
-        }
-
-        return xmlDoc;
-    };
-
-    FakeXMLHttpRequest.statusCodes = {
-        100: "Continue",
-        101: "Switching Protocols",
-        200: "OK",
-        201: "Created",
-        202: "Accepted",
-        203: "Non-Authoritative Information",
-        204: "No Content",
-        205: "Reset Content",
-        206: "Partial Content",
-        300: "Multiple Choice",
-        301: "Moved Permanently",
-        302: "Found",
-        303: "See Other",
-        304: "Not Modified",
-        305: "Use Proxy",
-        307: "Temporary Redirect",
-        400: "Bad Request",
-        401: "Unauthorized",
-        402: "Payment Required",
-        403: "Forbidden",
-        404: "Not Found",
-        405: "Method Not Allowed",
-        406: "Not Acceptable",
-        407: "Proxy Authentication Required",
-        408: "Request Timeout",
-        409: "Conflict",
-        410: "Gone",
-        411: "Length Required",
-        412: "Precondition Failed",
-        413: "Request Entity Too Large",
-        414: "Request-URI Too Long",
-        415: "Unsupported Media Type",
-        416: "Requested Range Not Satisfiable",
-        417: "Expectation Failed",
-        422: "Unprocessable Entity",
-        500: "Internal Server Error",
-        501: "Not Implemented",
-        502: "Bad Gateway",
-        503: "Service Unavailable",
-        504: "Gateway Timeout",
-        505: "HTTP Version Not Supported"
-    };
-
-    sinon.useFakeXMLHttpRequest = function () {
-        sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
-            if (xhr.supportsXHR) {
-                global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
-            }
-
-            if (xhr.supportsActiveX) {
-                global.ActiveXObject = xhr.GlobalActiveXObject;
-            }
-
-            delete sinon.FakeXMLHttpRequest.restore;
-
-            if (keepOnCreate !== true) {
-                delete sinon.FakeXMLHttpRequest.onCreate;
-            }
-        };
-        if (xhr.supportsXHR) {
-            global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
-        }
-
-        if (xhr.supportsActiveX) {
-            global.ActiveXObject = function ActiveXObject(objId) {
-                if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
-
-                    return new sinon.FakeXMLHttpRequest();
-                }
-
-                return new xhr.GlobalActiveXObject(objId);
-            };
-        }
-
-        return sinon.FakeXMLHttpRequest;
-    };
-
-    sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
-
-})(typeof global === "object" ? global : this);
-
-if (typeof module !== 'undefined' && module.exports) {
-    module.exports = sinon;
-}
-
-/**
- * @depend fake_xml_http_request.js
- */
-/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
-/*global module, require, window*/
-/**
- * The Sinon "server" mimics a web server that receives requests from
- * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
- * both synchronously and asynchronously. To respond synchronuously, canned
- * answers have to be provided upfront.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-if (typeof sinon == "undefined") {
-    var sinon = {};
-}
-
-sinon.fakeServer = (function () {
-    var push = [].push;
-    function F() {}
-
-    function create(proto) {
-        F.prototype = proto;
-        return new F();
-    }
-
-    function responseArray(handler) {
-        var response = handler;
-
-        if (Object.prototype.toString.call(handler) != "[object Array]") {
-            response = [200, {}, handler];
-        }
-
-        if (typeof response[2] != "string") {
-            throw new TypeError("Fake server response body should be string, but was " +
-                                typeof response[2]);
-        }
-
-        return response;
-    }
-
-    var wloc = typeof window !== "undefined" ? window.location : {};
-    var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
-
-    function matchOne(response, reqMethod, reqUrl) {
-        var rmeth = response.method;
-        var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
-        var url = response.url;
-        var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
-
-        return matchMethod && matchUrl;
-    }
-
-    function match(response, request) {
-        var requestUrl = request.url;
-
-        if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
-            requestUrl = requestUrl.replace(rCurrLoc, "");
-        }
-
-        if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
-            if (typeof response.response == "function") {
-                var ru = response.url;
-                var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
-                return response.response.apply(response, args);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    function log(response, request) {
-        var str;
-
-        str =  "Request:\n"  + sinon.format(request)  + "\n\n";
-        str += "Response:\n" + sinon.format(response) + "\n\n";
-
-        sinon.log(str);
-    }
-
-    return {
-        create: function () {
-            var server = create(this);
-            this.xhr = sinon.useFakeXMLHttpRequest();
-            server.requests = [];
-
-            this.xhr.onCreate = function (xhrObj) {
-                server.addRequest(xhrObj);
-            };
-
-            return server;
-        },
-
-        addRequest: function addRequest(xhrObj) {
-            var server = this;
-            push.call(this.requests, xhrObj);
-
-            xhrObj.onSend = function () {
-                server.handleRequest(this);
-
-                if (server.autoRespond && !server.responding) {
-                    setTimeout(function () {
-                        server.responding = false;
-                        server.respond();
-                    }, server.autoRespondAfter || 10);
-
-                    server.responding = true;
-                }
-            };
-        },
-
-        getHTTPMethod: function getHTTPMethod(request) {
-            if (this.fakeHTTPMethods && /post/i.test(request.method)) {
-                var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
-                return !!matches ? matches[1] : request.method;
-            }
-
-            return request.method;
-        },
-
-        handleRequest: function handleRequest(xhr) {
-            if (xhr.async) {
-                if (!this.queue) {
-                    this.queue = [];
-                }
-
-                push.call(this.queue, xhr);
-            } else {
-                this.processRequest(xhr);
-            }
-        },
-
-        respondWith: function respondWith(method, url, body) {
-            if (arguments.length == 1 && typeof method != "function") {
-                this.response = responseArray(method);
-                return;
-            }
-
-            if (!this.responses) { this.responses = []; }
-
-            if (arguments.length == 1) {
-                body = method;
-                url = method = null;
-            }
-
-            if (arguments.length == 2) {
-                body = url;
-                url = method;
-                method = null;
-            }
-
-            push.call(this.responses, {
-                method: method,
-                url: url,
-                response: typeof body == "function" ? body : responseArray(body)
-            });
-        },
-
-        respond: function respond() {
-            if (arguments.length > 0) this.respondWith.apply(this, arguments);
-            var queue = this.queue || [];
-            var requests = queue.splice(0);
-            var request;
-
-            while(request = requests.shift()) {
-                this.processRequest(request);
-            }
-        },
-
-        processRequest: function processRequest(request) {
-            try {
-                if (request.aborted) {
-                    return;
-                }
-
-                var response = this.response || [404, {}, ""];
-
-                if (this.responses) {
-                    for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
-                        if (match.call(this, this.responses[i], request)) {
-                            response = this.responses[i].response;
-                            break;
-                        }
-                    }
-                }
-
-                if (request.readyState != 4) {
-                    log(response, request);
-
-                    request.respond(response[0], response[1], response[2]);
-                }
-            } catch (e) {
-                sinon.logError("Fake server request processing", e);
-            }
-        },
-
-        restore: function restore() {
-            return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
-        }
-    };
-}());
-
-if (typeof module !== 'undefined' && module.exports) {
-    module.exports = sinon;
-}
-
-/**
- * @depend fake_server.js
- * @depend fake_timers.js
- */
-/*jslint browser: true, eqeqeq: false, onevar: false*/
-/*global sinon*/
-/**
- * Add-on for sinon.fakeServer that automatically handles a fake timer along with
- * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
- * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
- * it polls the object for completion with setInterval. Dispite the direct
- * motivation, there is nothing jQuery-specific in this file, so it can be used
- * in any environment where the ajax implementation depends on setInterval or
- * setTimeout.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function () {
-    function Server() {}
-    Server.prototype = sinon.fakeServer;
-
-    sinon.fakeServerWithClock = new Server();
-
-    sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
-        if (xhr.async) {
-            if (typeof setTimeout.clock == "object") {
-                this.clock = setTimeout.clock;
-            } else {
-                this.clock = sinon.useFakeTimers();
-                this.resetClock = true;
-            }
-
-            if (!this.longestTimeout) {
-                var clockSetTimeout = this.clock.setTimeout;
-                var clockSetInterval = this.clock.setInterval;
-                var server = this;
-
-                this.clock.setTimeout = function (fn, timeout) {
-                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
-
-                    return clockSetTimeout.apply(this, arguments);
-                };
-
-                this.clock.setInterval = function (fn, timeout) {
-                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
-
-                    return clockSetInterval.apply(this, arguments);
-                };
-            }
-        }
-
-        return sinon.fakeServer.addRequest.call(this, xhr);
-    };
-
-    sinon.fakeServerWithClock.respond = function respond() {
-        var returnVal = sinon.fakeServer.respond.apply(this, arguments);
-
-        if (this.clock) {
-            this.clock.tick(this.longestTimeout || 0);
-            this.longestTimeout = 0;
-
-            if (this.resetClock) {
-                this.clock.restore();
-                this.resetClock = false;
-            }
-        }
-
-        return returnVal;
-    };
-
-    sinon.fakeServerWithClock.restore = function restore() {
-        if (this.clock) {
-            this.clock.restore();
-        }
-
-        return sinon.fakeServer.restore.apply(this, arguments);
-    };
-}());
-
-/**
- * @depend ../sinon.js
- * @depend collection.js
- * @depend util/fake_timers.js
- * @depend util/fake_server_with_clock.js
- */
-/*jslint eqeqeq: false, onevar: false, plusplus: false*/
-/*global require, module*/
-/**
- * Manages fake collections as well as fake utilities such as Sinon's
- * timers and fake XHR implementation in one convenient object.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-if (typeof module !== 'undefined' && module.exports) {
-    var sinon = require("../sinon");
-    sinon.extend(sinon, require("./util/fake_timers"));
-}
-
-(function () {
-    var push = [].push;
-
-    function exposeValue(sandbox, config, key, value) {
-        if (!value) {
-            return;
-        }
-
-        if (config.injectInto && !(key in config.injectInto) ) {
-            config.injectInto[key] = value;
-        } else {
-            push.call(sandbox.args, value);
-        }
-    }
-
-    function prepareSandboxFromConfig(config) {
-        var sandbox = sinon.create(sinon.sandbox);
-
-        if (config.useFakeServer) {
-            if (typeof config.useFakeServer == "object") {
-                sandbox.serverPrototype = config.useFakeServer;
-            }
-
-            sandbox.useFakeServer();
-        }
-
-        if (config.useFakeTimers) {
-            if (typeof config.useFakeTimers == "object") {
-                sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
-            } else {
-                sandbox.useFakeTimers();
-            }
-        }
-
-        return sandbox;
-    }
-
-    sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
-        useFakeTimers: function useFakeTimers() {
-            this.clock = sinon.useFakeTimers.apply(sinon, arguments);
-
-            return this.add(this.clock);
-        },
-
-        serverPrototype: sinon.fakeServer,
-
-        useFakeServer: function useFakeServer() {
-            var proto = this.serverPrototype || sinon.fakeServer;
-
-            if (!proto || !proto.create) {
-                return null;
-            }
-
-            this.server = proto.create();
-            return this.add(this.server);
-        },
-
-        inject: function (obj) {
-            sinon.collection.inject.call(this, obj);
-
-            if (this.clock) {
-                obj.clock = this.clock;
-            }
-
-            if (this.server) {
-                obj.server = this.server;
-                obj.requests = this.server.requests;
-            }
-
-            return obj;
-        },
-
-        create: function (config) {
-            if (!config) {
-                return sinon.create(sinon.sandbox);
-            }
-
-            var sandbox = prepareSandboxFromConfig(config);
-            sandbox.args = sandbox.args || [];
-            var prop, value, exposed = sandbox.inject({});
-
-            if (config.properties) {
-                for (var i = 0, l = config.properties.length; i < l; i++) {
-                    prop = config.properties[i];
-                    value = exposed[prop] || prop == "sandbox" && sandbox;
-                    exposeValue(sandbox, config, prop, value);
-                }
-            } else {
-                exposeValue(sandbox, config, "sandbox", value);
-            }
-
-            return sandbox;
-        }
-    });
-
-    sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
-
-    if (typeof module !== 'undefined' && module.exports) {
-        module.exports = sinon.sandbox;
-    }
-}());
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- * @depend mock.js
- * @depend sandbox.js
- */
-/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Test function, sandboxes fakes
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function test(callback) {
-        var type = typeof callback;
-
-        if (type != "function") {
-            throw new TypeError("sinon.test needs to wrap a test function, got " + type);
-        }
-
-        return function () {
-            var config = sinon.getConfig(sinon.config);
-            config.injectInto = config.injectIntoThis && this || config.injectInto;
-            var sandbox = sinon.sandbox.create(config);
-            var exception, result;
-            var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
-
-            try {
-                result = callback.apply(this, args);
-            } catch (e) {
-                exception = e;
-            }
-
-            if (typeof exception !== "undefined") {
-                sandbox.restore();
-                throw exception;
-            }
-            else {
-                sandbox.verifyAndRestore();
-            }
-
-            return result;
-        };
-    }
-
-    test.config = {
-        injectIntoThis: true,
-        injectInto: null,
-        properties: ["spy", "stub", "mock", "clock", "server", "requests"],
-        useFakeTimers: true,
-        useFakeServer: true
-    };
-
-    if (commonJSModule) {
-        module.exports = test;
-    } else {
-        sinon.test = test;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend test.js
- */
-/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
-/*global module, require, sinon*/
-/**
- * Test case, sandboxes all test functions
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon) {
-    var commonJSModule = typeof module !== 'undefined' && module.exports;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon || !Object.prototype.hasOwnProperty) {
-        return;
-    }
-
-    function createTest(property, setUp, tearDown) {
-        return function () {
-            if (setUp) {
-                setUp.apply(this, arguments);
-            }
-
-            var exception, result;
-
-            try {
-                result = property.apply(this, arguments);
-            } catch (e) {
-                exception = e;
-            }
-
-            if (tearDown) {
-                tearDown.apply(this, arguments);
-            }
-
-            if (exception) {
-                throw exception;
-            }
-
-            return result;
-        };
-    }
-
-    function testCase(tests, prefix) {
-        /*jsl:ignore*/
-        if (!tests || typeof tests != "object") {
-            throw new TypeError("sinon.testCase needs an object with test functions");
-        }
-        /*jsl:end*/
-
-        prefix = prefix || "test";
-        var rPrefix = new RegExp("^" + prefix);
-        var methods = {}, testName, property, method;
-        var setUp = tests.setUp;
-        var tearDown = tests.tearDown;
-
-        for (testName in tests) {
-            if (tests.hasOwnProperty(testName)) {
-                property = tests[testName];
-
-                if (/^(setUp|tearDown)$/.test(testName)) {
-                    continue;
-                }
-
-                if (typeof property == "function" && rPrefix.test(testName)) {
-                    method = property;
-
-                    if (setUp || tearDown) {
-                        method = createTest(property, setUp, tearDown);
-                    }
-
-                    methods[testName] = sinon.test(method);
-                } else {
-                    methods[testName] = tests[testName];
-                }
-            }
-        }
-
-        return methods;
-    }
-
-    if (commonJSModule) {
-        module.exports = testCase;
-    } else {
-        sinon.testCase = testCase;
-    }
-}(typeof sinon == "object" && sinon || null));
-
-/**
- * @depend ../sinon.js
- * @depend stub.js
- */
-/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
-/*global module, require, sinon*/
-/**
- * Assertions matching the test spy retrieval interface.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-
-(function (sinon, global) {
-    var commonJSModule = typeof module !== "undefined" && module.exports;
-    var slice = Array.prototype.slice;
-    var assert;
-
-    if (!sinon && commonJSModule) {
-        sinon = require("../sinon");
-    }
-
-    if (!sinon) {
-        return;
-    }
-
-    function verifyIsStub() {
-        var method;
-
-        for (var i = 0, l = arguments.length; i < l; ++i) {
-            method = arguments[i];
-
-            if (!method) {
-                assert.fail("fake is not a spy");
-            }
-
-            if (typeof method != "function") {
-                assert.fail(method + " is not a function");
-            }
-
-            if (typeof method.getCall != "function") {
-                assert.fail(method + " is not stubbed");
-            }
-        }
-    }
-
-    function failAssertion(object, msg) {
-        object = object || global;
-        var failMethod = object.fail || assert.fail;
-        failMethod.call(object, msg);
-    }
-
-    function mirrorPropAsAssertion(name, method, message) {
-        if (arguments.length == 2) {
-            message = method;
-            method = name;
-        }
-
-        assert[name] = function (fake) {
-            verifyIsStub(fake);
-
-            var args = slice.call(arguments, 1);
-            var failed = false;
-
-            if (typeof method == "function") {
-                failed = !method(fake);
-            } else {
-                failed = typeof fake[method] == "function" ?
-                    !fake[method].apply(fake, args) : !fake[method];
-            }
-
-            if (failed) {
-                failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
-            } else {
-                assert.pass(name);
-            }
-        };
-    }
-
-    function exposedName(prefix, prop) {
-        return !prefix || /^fail/.test(prop) ? prop :
-            prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
-    }
-
-    assert = {
-        failException: "AssertError",
-
-        fail: function fail(message) {
-            var error = new Error(message);
-            error.name = this.failException || assert.failException;
-
-            throw error;
-        },
-
-        pass: function pass(assertion) {},
-
-        callOrder: function assertCallOrder() {
-            verifyIsStub.apply(null, arguments);
-            var expected = "", actual = "";
-
-            if (!sinon.calledInOrder(arguments)) {
-                try {
-                    expected = [].join.call(arguments, ", ");
-                    var calls = slice.call(arguments);
-                    var i = calls.length;
-                    while (i) {
-                        if (!calls[--i].called) {
-                            calls.splice(i, 1);
-                        }
-                    }
-                    actual = sinon.orderByFirstCall(calls).join(", ");
-                } catch (e) {
-                    // If this fails, we'll just fall back to the blank string
-                }
-
-                failAssertion(this, "expected " + expected + " to be " +
-                              "called in order but were called as " + actual);
-            } else {
-                assert.pass("callOrder");
-            }
-        },
-
-        callCount: function assertCallCount(method, count) {
-            verifyIsStub(method);
-
-            if (method.callCount != count) {
-                var msg = "expected %n to be called " + sinon.timesInWords(count) +
-                    " but was called %c%C";
-                failAssertion(this, method.printf(msg));
-            } else {
-                assert.pass("callCount");
-            }
-        },
-
-        expose: function expose(target, options) {
-            if (!target) {
-                throw new TypeError("target is null or undefined");
-            }
-
-            var o = options || {};
-            var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
-            var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
-
-            for (var method in this) {
-                if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
-                    target[exposedName(prefix, method)] = this[method];
-                }
-            }
-
-            return target;
-        }
-    };
-
-    mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
-    mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
-                          "expected %n to not have been called but was called %c%C");
-    mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
-    mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
-    mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
-    mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
-    mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
-    mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
-    mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
-    mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
-    mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
-    mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
-    mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
-    mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
-    mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
-    mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
-    mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
-    mirrorPropAsAssertion("threw", "%n did not throw exception%C");
-    mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
-
-    if (commonJSModule) {
-        module.exports = assert;
-    } else {
-        sinon.assert = assert;
-    }
-}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
-
-return sinon;}.call(typeof window != 'undefined' && window || {}));
diff --git a/resources/sinonjs/sinon-1.9.0.js b/resources/sinonjs/sinon-1.9.0.js
new file mode 100644 (file)
index 0000000..428b729
--- /dev/null
@@ -0,0 +1,4794 @@
+/**
+ * Sinon.JS 1.9.0, 2014/03/05
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+this.sinon = (function () {
+var samsam, formatio;
+function define(mod, deps, fn) { if (mod == "samsam") { samsam = deps(); } else { formatio = fn(samsam); } }
+define.amd = true;
+((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
+ (typeof module === "object" &&
+      function (m) { module.exports = m(); }) || // Node
+ function (m) { this.samsam = m(); } // Browser globals
+)(function () {
+    var o = Object.prototype;
+    var div = typeof document !== "undefined" && document.createElement("div");
+
+    function isNaN(value) {
+        // Unlike global isNaN, this avoids type coercion
+        // typeof check avoids IE host object issues, hat tip to
+        // lodash
+        var val = value; // JsLint thinks value !== value is "weird"
+        return typeof value === "number" && value !== val;
+    }
+
+    function getClass(value) {
+        // Returns the internal [[Class]] by calling Object.prototype.toString
+        // with the provided value as this. Return value is a string, naming the
+        // internal class, e.g. "Array"
+        return o.toString.call(value).split(/[ \]]/)[1];
+    }
+
+    /**
+     * @name samsam.isArguments
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is an ``arguments`` object,
+     * ``false`` otherwise.
+     */
+    function isArguments(object) {
+        if (typeof object !== "object" || typeof object.length !== "number" ||
+                getClass(object) === "Array") {
+            return false;
+        }
+        if (typeof object.callee == "function") { return true; }
+        try {
+            object[object.length] = 6;
+            delete object[object.length];
+        } catch (e) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.isElement
+     * @param Object object
+     *
+     * Returns ``true`` if ``object`` is a DOM element node. Unlike
+     * Underscore.js/lodash, this function will return ``false`` if ``object``
+     * is an *element-like* object, i.e. a regular object with a ``nodeType``
+     * property that holds the value ``1``.
+     */
+    function isElement(object) {
+        if (!object || object.nodeType !== 1 || !div) { return false; }
+        try {
+            object.appendChild(div);
+            object.removeChild(div);
+        } catch (e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @name samsam.keys
+     * @param Object object
+     *
+     * Return an array of own property names.
+     */
+    function keys(object) {
+        var ks = [], prop;
+        for (prop in object) {
+            if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
+        }
+        return ks;
+    }
+
+    /**
+     * @name samsam.isDate
+     * @param Object value
+     *
+     * Returns true if the object is a ``Date``, or *date-like*. Duck typing
+     * of date objects work by checking that the object has a ``getTime``
+     * function whose return value equals the return value from the object's
+     * ``valueOf``.
+     */
+    function isDate(value) {
+        return typeof value.getTime == "function" &&
+            value.getTime() == value.valueOf();
+    }
+
+    /**
+     * @name samsam.isNegZero
+     * @param Object value
+     *
+     * Returns ``true`` if ``value`` is ``-0``.
+     */
+    function isNegZero(value) {
+        return value === 0 && 1 / value === -Infinity;
+    }
+
+    /**
+     * @name samsam.equal
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Returns ``true`` if two objects are strictly equal. Compared to
+     * ``===`` there are two exceptions:
+     *
+     *   - NaN is considered equal to NaN
+     *   - -0 and +0 are not considered equal
+     */
+    function identical(obj1, obj2) {
+        if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
+            return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
+        }
+    }
+
+
+    /**
+     * @name samsam.deepEqual
+     * @param Object obj1
+     * @param Object obj2
+     *
+     * Deep equal comparison. Two values are "deep equal" if:
+     *
+     *   - They are equal, according to samsam.identical
+     *   - They are both date objects representing the same time
+     *   - They are both arrays containing elements that are all deepEqual
+     *   - They are objects with the same set of properties, and each property
+     *     in ``obj1`` is deepEqual to the corresponding property in ``obj2``
+     *
+     * Supports cyclic objects.
+     */
+    function deepEqualCyclic(obj1, obj2) {
+
+        // used for cyclic comparison
+        // contain already visited objects
+        var objects1 = [],
+            objects2 = [],
+        // contain pathes (position in the object structure)
+        // of the already visited objects
+        // indexes same as in objects arrays
+            paths1 = [],
+            paths2 = [],
+        // contains combinations of already compared objects
+        // in the manner: { "$1['ref']$2['ref']": true }
+            compared = {};
+
+        /**
+         * used to check, if the value of a property is an object
+         * (cyclic logic is only needed for objects)
+         * only needed for cyclic logic
+         */
+        function isObject(value) {
+
+            if (typeof value === 'object' && value !== null &&
+                    !(value instanceof Boolean) &&
+                    !(value instanceof Date)    &&
+                    !(value instanceof Number)  &&
+                    !(value instanceof RegExp)  &&
+                    !(value instanceof String)) {
+
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * returns the index of the given object in the
+         * given objects array, -1 if not contained
+         * only needed for cyclic logic
+         */
+        function getIndex(objects, obj) {
+
+            var i;
+            for (i = 0; i < objects.length; i++) {
+                if (objects[i] === obj) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+
+        // does the recursion for the deep equal check
+        return (function deepEqual(obj1, obj2, path1, path2) {
+            var type1 = typeof obj1;
+            var type2 = typeof obj2;
+
+            // == null also matches undefined
+            if (obj1 === obj2 ||
+                    isNaN(obj1) || isNaN(obj2) ||
+                    obj1 == null || obj2 == null ||
+                    type1 !== "object" || type2 !== "object") {
+
+                return identical(obj1, obj2);
+            }
+
+            // Elements are only equal if identical(expected, actual)
+            if (isElement(obj1) || isElement(obj2)) { return false; }
+
+            var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
+            if (isDate1 || isDate2) {
+                if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
+                    return false;
+                }
+            }
+
+            if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
+                if (obj1.toString() !== obj2.toString()) { return false; }
+            }
+
+            var class1 = getClass(obj1);
+            var class2 = getClass(obj2);
+            var keys1 = keys(obj1);
+            var keys2 = keys(obj2);
+
+            if (isArguments(obj1) || isArguments(obj2)) {
+                if (obj1.length !== obj2.length) { return false; }
+            } else {
+                if (type1 !== type2 || class1 !== class2 ||
+                        keys1.length !== keys2.length) {
+                    return false;
+                }
+            }
+
+            var key, i, l,
+                // following vars are used for the cyclic logic
+                value1, value2,
+                isObject1, isObject2,
+                index1, index2,
+                newPath1, newPath2;
+
+            for (i = 0, l = keys1.length; i < l; i++) {
+                key = keys1[i];
+                if (!o.hasOwnProperty.call(obj2, key)) {
+                    return false;
+                }
+
+                // Start of the cyclic logic
+
+                value1 = obj1[key];
+                value2 = obj2[key];
+
+                isObject1 = isObject(value1);
+                isObject2 = isObject(value2);
+
+                // determine, if the objects were already visited
+                // (it's faster to check for isObject first, than to
+                // get -1 from getIndex for non objects)
+                index1 = isObject1 ? getIndex(objects1, value1) : -1;
+                index2 = isObject2 ? getIndex(objects2, value2) : -1;
+
+                // determine the new pathes of the objects
+                // - for non cyclic objects the current path will be extended
+                //   by current property name
+                // - for cyclic objects the stored path is taken
+                newPath1 = index1 !== -1
+                    ? paths1[index1]
+                    : path1 + '[' + JSON.stringify(key) + ']';
+                newPath2 = index2 !== -1
+                    ? paths2[index2]
+                    : path2 + '[' + JSON.stringify(key) + ']';
+
+                // stop recursion if current objects are already compared
+                if (compared[newPath1 + newPath2]) {
+                    return true;
+                }
+
+                // remember the current objects and their pathes
+                if (index1 === -1 && isObject1) {
+                    objects1.push(value1);
+                    paths1.push(newPath1);
+                }
+                if (index2 === -1 && isObject2) {
+                    objects2.push(value2);
+                    paths2.push(newPath2);
+                }
+
+                // remember that the current objects are already compared
+                if (isObject1 && isObject2) {
+                    compared[newPath1 + newPath2] = true;
+                }
+
+                // End of cyclic logic
+
+                // neither value1 nor value2 is a cycle
+                // continue with next level
+                if (!deepEqual(value1, value2, newPath1, newPath2)) {
+                    return false;
+                }
+            }
+
+            return true;
+
+        }(obj1, obj2, '$1', '$2'));
+    }
+
+    var match;
+
+    function arrayContains(array, subset) {
+        if (subset.length === 0) { return true; }
+        var i, l, j, k;
+        for (i = 0, l = array.length; i < l; ++i) {
+            if (match(array[i], subset[0])) {
+                for (j = 0, k = subset.length; j < k; ++j) {
+                    if (!match(array[i + j], subset[j])) { return false; }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @name samsam.match
+     * @param Object object
+     * @param Object matcher
+     *
+     * Compare arbitrary value ``object`` with matcher.
+     */
+    match = function match(object, matcher) {
+        if (matcher && typeof matcher.test === "function") {
+            return matcher.test(object);
+        }
+
+        if (typeof matcher === "function") {
+            return matcher(object) === true;
+        }
+
+        if (typeof matcher === "string") {
+            matcher = matcher.toLowerCase();
+            var notNull = typeof object === "string" || !!object;
+            return notNull &&
+                (String(object)).toLowerCase().indexOf(matcher) >= 0;
+        }
+
+        if (typeof matcher === "number") {
+            return matcher === object;
+        }
+
+        if (typeof matcher === "boolean") {
+            return matcher === object;
+        }
+
+        if (getClass(object) === "Array" && getClass(matcher) === "Array") {
+            return arrayContains(object, matcher);
+        }
+
+        if (matcher && typeof matcher === "object") {
+            var prop;
+            for (prop in matcher) {
+                if (!match(object[prop], matcher[prop])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        throw new Error("Matcher was not a string, a number, a " +
+                        "function, a boolean or an object");
+    };
+
+    return {
+        isArguments: isArguments,
+        isElement: isElement,
+        isDate: isDate,
+        isNegZero: isNegZero,
+        identical: identical,
+        deepEqual: deepEqualCyclic,
+        match: match,
+        keys: keys
+    };
+});
+((typeof define === "function" && define.amd && function (m) {
+    define("formatio", ["samsam"], m);
+}) || (typeof module === "object" && function (m) {
+    module.exports = m(require("samsam"));
+}) || function (m) { this.formatio = m(this.samsam); }
+)(function (samsam) {
+    
+    var formatio = {
+        excludeConstructors: ["Object", /^.$/],
+        quoteStrings: true
+    };
+
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    var specialObjects = [];
+    if (typeof global !== "undefined") {
+        specialObjects.push({ object: global, value: "[object global]" });
+    }
+    if (typeof document !== "undefined") {
+        specialObjects.push({
+            object: document,
+            value: "[object HTMLDocument]"
+        });
+    }
+    if (typeof window !== "undefined") {
+        specialObjects.push({ object: window, value: "[object Window]" });
+    }
+
+    function functionName(func) {
+        if (!func) { return ""; }
+        if (func.displayName) { return func.displayName; }
+        if (func.name) { return func.name; }
+        var matches = func.toString().match(/function\s+([^\(]+)/m);
+        return (matches && matches[1]) || "";
+    }
+
+    function constructorName(f, object) {
+        var name = functionName(object && object.constructor);
+        var excludes = f.excludeConstructors ||
+                formatio.excludeConstructors || [];
+
+        var i, l;
+        for (i = 0, l = excludes.length; i < l; ++i) {
+            if (typeof excludes[i] === "string" && excludes[i] === name) {
+                return "";
+            } else if (excludes[i].test && excludes[i].test(name)) {
+                return "";
+            }
+        }
+
+        return name;
+    }
+
+    function isCircular(object, objects) {
+        if (typeof object !== "object") { return false; }
+        var i, l;
+        for (i = 0, l = objects.length; i < l; ++i) {
+            if (objects[i] === object) { return true; }
+        }
+        return false;
+    }
+
+    function ascii(f, object, processed, indent) {
+        if (typeof object === "string") {
+            var qs = f.quoteStrings;
+            var quote = typeof qs !== "boolean" || qs;
+            return processed || quote ? '"' + object + '"' : object;
+        }
+
+        if (typeof object === "function" && !(object instanceof RegExp)) {
+            return ascii.func(object);
+        }
+
+        processed = processed || [];
+
+        if (isCircular(object, processed)) { return "[Circular]"; }
+
+        if (Object.prototype.toString.call(object) === "[object Array]") {
+            return ascii.array.call(f, object, processed);
+        }
+
+        if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
+        if (samsam.isElement(object)) { return ascii.element(object); }
+
+        if (typeof object.toString === "function" &&
+                object.toString !== Object.prototype.toString) {
+            return object.toString();
+        }
+
+        var i, l;
+        for (i = 0, l = specialObjects.length; i < l; i++) {
+            if (object === specialObjects[i].object) {
+                return specialObjects[i].value;
+            }
+        }
+
+        return ascii.object.call(f, object, processed, indent);
+    }
+
+    ascii.func = function (func) {
+        return "function " + functionName(func) + "() {}";
+    };
+
+    ascii.array = function (array, processed) {
+        processed = processed || [];
+        processed.push(array);
+        var i, l, pieces = [];
+        for (i = 0, l = array.length; i < l; ++i) {
+            pieces.push(ascii(this, array[i], processed));
+        }
+        return "[" + pieces.join(", ") + "]";
+    };
+
+    ascii.object = function (object, processed, indent) {
+        processed = processed || [];
+        processed.push(object);
+        indent = indent || 0;
+        var pieces = [], properties = samsam.keys(object).sort();
+        var length = 3;
+        var prop, str, obj, i, l;
+
+        for (i = 0, l = properties.length; i < l; ++i) {
+            prop = properties[i];
+            obj = object[prop];
+
+            if (isCircular(obj, processed)) {
+                str = "[Circular]";
+            } else {
+                str = ascii(this, obj, processed, indent + 2);
+            }
+
+            str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
+            length += str.length;
+            pieces.push(str);
+        }
+
+        var cons = constructorName(this, object);
+        var prefix = cons ? "[" + cons + "] " : "";
+        var is = "";
+        for (i = 0, l = indent; i < l; ++i) { is += " "; }
+
+        if (length + indent > 80) {
+            return prefix + "{\n  " + is + pieces.join(",\n  " + is) + "\n" +
+                is + "}";
+        }
+        return prefix + "{ " + pieces.join(", ") + " }";
+    };
+
+    ascii.element = function (element) {
+        var tagName = element.tagName.toLowerCase();
+        var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
+
+        for (i = 0, l = attrs.length; i < l; ++i) {
+            attr = attrs.item(i);
+            attrName = attr.nodeName.toLowerCase().replace("html:", "");
+            val = attr.nodeValue;
+            if (attrName !== "contenteditable" || val !== "inherit") {
+                if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
+            }
+        }
+
+        var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
+        var content = element.innerHTML;
+
+        if (content.length > 20) {
+            content = content.substr(0, 20) + "[...]";
+        }
+
+        var res = formatted + pairs.join(" ") + ">" + content +
+                "</" + tagName + ">";
+
+        return res.replace(/ contentEditable="inherit"/, "");
+    };
+
+    function Formatio(options) {
+        for (var opt in options) {
+            this[opt] = options[opt];
+        }
+    }
+
+    Formatio.prototype = {
+        functionName: functionName,
+
+        configure: function (options) {
+            return new Formatio(options);
+        },
+
+        constructorName: function (object) {
+            return constructorName(this, object);
+        },
+
+        ascii: function (object, processed, indent) {
+            return ascii(this, object, processed, indent);
+        }
+    };
+
+    return Formatio.prototype;
+});
+/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
+/*global module, require, __dirname, document*/
+/**
+ * Sinon core utilities. For internal use only.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+var sinon = (function (formatio) {
+    var div = typeof document != "undefined" && document.createElement("div");
+    var hasOwn = Object.prototype.hasOwnProperty;
+
+    function isDOMNode(obj) {
+        var success = false;
+
+        try {
+            obj.appendChild(div);
+            success = div.parentNode == obj;
+        } catch (e) {
+            return false;
+        } finally {
+            try {
+                obj.removeChild(div);
+            } catch (e) {
+                // Remove failed, not much we can do about that
+            }
+        }
+
+        return success;
+    }
+
+    function isElement(obj) {
+        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
+    }
+
+    function isFunction(obj) {
+        return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
+    }
+
+    function mirrorProperties(target, source) {
+        for (var prop in source) {
+            if (!hasOwn.call(target, prop)) {
+                target[prop] = source[prop];
+            }
+        }
+    }
+
+    function isRestorable (obj) {
+        return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
+    }
+
+    var sinon = {
+        wrapMethod: function wrapMethod(object, property, method) {
+            if (!object) {
+                throw new TypeError("Should wrap property of object");
+            }
+
+            if (typeof method != "function") {
+                throw new TypeError("Method wrapper should be function");
+            }
+
+            var wrappedMethod = object[property],
+                error;
+
+            if (!isFunction(wrappedMethod)) {
+                error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
+                                    property + " as function");
+            }
+
+            if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
+                error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
+            }
+
+            if (wrappedMethod.calledBefore) {
+                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
+                error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
+            }
+
+            if (error) {
+                if (wrappedMethod._stack) {
+                    error.stack += '\n--------------\n' + wrappedMethod._stack;
+                }
+                throw error;
+            }
+
+            // IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
+            // when using hasOwn.call on objects from other frames.
+            var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
+            object[property] = method;
+            method.displayName = property;
+            // Set up a stack trace which can be used later to find what line of
+            // code the original method was created on.
+            method._stack = (new Error('Stack Trace for original')).stack;
+
+            method.restore = function () {
+                // For prototype properties try to reset by delete first.
+                // If this fails (ex: localStorage on mobile safari) then force a reset
+                // via direct assignment.
+                if (!owned) {
+                    delete object[property];
+                }
+                if (object[property] === method) {
+                    object[property] = wrappedMethod;
+                }
+            };
+
+            method.restore.sinon = true;
+            mirrorProperties(method, wrappedMethod);
+
+            return method;
+        },
+
+        extend: function extend(target) {
+            for (var i = 1, l = arguments.length; i < l; i += 1) {
+                for (var prop in arguments[i]) {
+                    if (arguments[i].hasOwnProperty(prop)) {
+                        target[prop] = arguments[i][prop];
+                    }
+
+                    // DONT ENUM bug, only care about toString
+                    if (arguments[i].hasOwnProperty("toString") &&
+                        arguments[i].toString != target.toString) {
+                        target.toString = arguments[i].toString;
+                    }
+                }
+            }
+
+            return target;
+        },
+
+        create: function create(proto) {
+            var F = function () {};
+            F.prototype = proto;
+            return new F();
+        },
+
+        deepEqual: function deepEqual(a, b) {
+            if (sinon.match && sinon.match.isMatcher(a)) {
+                return a.test(b);
+            }
+            if (typeof a != "object" || typeof b != "object") {
+                return a === b;
+            }
+
+            if (isElement(a) || isElement(b)) {
+                return a === b;
+            }
+
+            if (a === b) {
+                return true;
+            }
+
+            if ((a === null && b !== null) || (a !== null && b === null)) {
+                return false;
+            }
+
+            if (a instanceof RegExp && b instanceof RegExp) {
+              return (a.source === b.source) && (a.global === b.global) && 
+                (a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
+            }
+
+            var aString = Object.prototype.toString.call(a);
+            if (aString != Object.prototype.toString.call(b)) {
+                return false;
+            }
+
+            if (aString == "[object Date]") {
+                return a.valueOf() === b.valueOf();
+            }
+
+            var prop, aLength = 0, bLength = 0;
+
+            if (aString == "[object Array]" && a.length !== b.length) {
+                return false;
+            }
+
+            for (prop in a) {
+                aLength += 1;
+
+                if (!deepEqual(a[prop], b[prop])) {
+                    return false;
+                }
+            }
+
+            for (prop in b) {
+                bLength += 1;
+            }
+
+            return aLength == bLength;
+        },
+
+        functionName: function functionName(func) {
+            var name = func.displayName || func.name;
+
+            // Use function decomposition as a last resort to get function
+            // name. Does not rely on function decomposition to work - if it
+            // doesn't debugging will be slightly less informative
+            // (i.e. toString will say 'spy' rather than 'myFunc').
+            if (!name) {
+                var matches = func.toString().match(/function ([^\s\(]+)/);
+                name = matches && matches[1];
+            }
+
+            return name;
+        },
+
+        functionToString: function toString() {
+            if (this.getCall && this.callCount) {
+                var thisValue, prop, i = this.callCount;
+
+                while (i--) {
+                    thisValue = this.getCall(i).thisValue;
+
+                    for (prop in thisValue) {
+                        if (thisValue[prop] === this) {
+                            return prop;
+                        }
+                    }
+                }
+            }
+
+            return this.displayName || "sinon fake";
+        },
+
+        getConfig: function (custom) {
+            var config = {};
+            custom = custom || {};
+            var defaults = sinon.defaultConfig;
+
+            for (var prop in defaults) {
+                if (defaults.hasOwnProperty(prop)) {
+                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
+                }
+            }
+
+            return config;
+        },
+
+        format: function (val) {
+            return "" + val;
+        },
+
+        defaultConfig: {
+            injectIntoThis: true,
+            injectInto: null,
+            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+            useFakeTimers: true,
+            useFakeServer: true
+        },
+
+        timesInWords: function timesInWords(count) {
+            return count == 1 && "once" ||
+                count == 2 && "twice" ||
+                count == 3 && "thrice" ||
+                (count || 0) + " times";
+        },
+
+        calledInOrder: function (spies) {
+            for (var i = 1, l = spies.length; i < l; i++) {
+                if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        orderByFirstCall: function (spies) {
+            return spies.sort(function (a, b) {
+                // uuid, won't ever be equal
+                var aCall = a.getCall(0);
+                var bCall = b.getCall(0);
+                var aId = aCall && aCall.callId || -1;
+                var bId = bCall && bCall.callId || -1;
+
+                return aId < bId ? -1 : 1;
+            });
+        },
+
+        log: function () {},
+
+        logError: function (label, err) {
+            var msg = label + " threw exception: ";
+            sinon.log(msg + "[" + err.name + "] " + err.message);
+            if (err.stack) { sinon.log(err.stack); }
+
+            setTimeout(function () {
+                err.message = msg + err.message;
+                throw err;
+            }, 0);
+        },
+
+        typeOf: function (value) {
+            if (value === null) {
+                return "null";
+            }
+            else if (value === undefined) {
+                return "undefined";
+            }
+            var string = Object.prototype.toString.call(value);
+            return string.substring(8, string.length - 1).toLowerCase();
+        },
+
+        createStubInstance: function (constructor) {
+            if (typeof constructor !== "function") {
+                throw new TypeError("The constructor should be a function.");
+            }
+            return sinon.stub(sinon.create(constructor.prototype));
+        },
+
+        restore: function (object) {
+            if (object !== null && typeof object === "object") {
+                for (var prop in object) {
+                    if (isRestorable(object[prop])) {
+                        object[prop].restore();
+                    }
+                }
+            }
+            else if (isRestorable(object)) {
+                object.restore();
+            }
+        }
+    };
+
+    var isNode = typeof module !== "undefined" && module.exports;
+    var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
+
+    if (isAMD) {
+        define(function(){
+            return sinon;
+        });
+    } else if (isNode) {
+        try {
+            formatio = require("formatio");
+        } catch (e) {}
+        module.exports = sinon;
+        module.exports.spy = require("./sinon/spy");
+        module.exports.spyCall = require("./sinon/call");
+        module.exports.behavior = require("./sinon/behavior");
+        module.exports.stub = require("./sinon/stub");
+        module.exports.mock = require("./sinon/mock");
+        module.exports.collection = require("./sinon/collection");
+        module.exports.assert = require("./sinon/assert");
+        module.exports.sandbox = require("./sinon/sandbox");
+        module.exports.test = require("./sinon/test");
+        module.exports.testCase = require("./sinon/test_case");
+        module.exports.assert = require("./sinon/assert");
+        module.exports.match = require("./sinon/match");
+    }
+
+    if (formatio) {
+        var formatter = formatio.configure({ quoteStrings: false });
+        sinon.format = function () {
+            return formatter.ascii.apply(formatter, arguments);
+        };
+    } else if (isNode) {
+        try {
+            var util = require("util");
+            sinon.format = function (value) {
+                return typeof value == "object" && value.toString === Object.prototype.toString ? util.inspect(value) : value;
+            };
+        } catch (e) {
+            /* Node, but no util module - would be very old, but better safe than
+             sorry */
+        }
+    }
+
+    return sinon;
+}(typeof formatio == "object" && formatio));
+
+/* @depend ../sinon.js */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Match functions
+ *
+ * @author Maximilian Antoni (mail@maxantoni.de)
+ * @license BSD
+ *
+ * Copyright (c) 2012 Maximilian Antoni
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function assertType(value, type, name) {
+        var actual = sinon.typeOf(value);
+        if (actual !== type) {
+            throw new TypeError("Expected type of " + name + " to be " +
+                type + ", but was " + actual);
+        }
+    }
+
+    var matcher = {
+        toString: function () {
+            return this.message;
+        }
+    };
+
+    function isMatcher(object) {
+        return matcher.isPrototypeOf(object);
+    }
+
+    function matchObject(expectation, actual) {
+        if (actual === null || actual === undefined) {
+            return false;
+        }
+        for (var key in expectation) {
+            if (expectation.hasOwnProperty(key)) {
+                var exp = expectation[key];
+                var act = actual[key];
+                if (match.isMatcher(exp)) {
+                    if (!exp.test(act)) {
+                        return false;
+                    }
+                } else if (sinon.typeOf(exp) === "object") {
+                    if (!matchObject(exp, act)) {
+                        return false;
+                    }
+                } else if (!sinon.deepEqual(exp, act)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    matcher.or = function (m2) {
+        if (!arguments.length) {
+            throw new TypeError("Matcher expected");
+        } else if (!isMatcher(m2)) {
+            m2 = match(m2);
+        }
+        var m1 = this;
+        var or = sinon.create(matcher);
+        or.test = function (actual) {
+            return m1.test(actual) || m2.test(actual);
+        };
+        or.message = m1.message + ".or(" + m2.message + ")";
+        return or;
+    };
+
+    matcher.and = function (m2) {
+        if (!arguments.length) {
+            throw new TypeError("Matcher expected");
+        } else if (!isMatcher(m2)) {
+            m2 = match(m2);
+        }
+        var m1 = this;
+        var and = sinon.create(matcher);
+        and.test = function (actual) {
+            return m1.test(actual) && m2.test(actual);
+        };
+        and.message = m1.message + ".and(" + m2.message + ")";
+        return and;
+    };
+
+    var match = function (expectation, message) {
+        var m = sinon.create(matcher);
+        var type = sinon.typeOf(expectation);
+        switch (type) {
+        case "object":
+            if (typeof expectation.test === "function") {
+                m.test = function (actual) {
+                    return expectation.test(actual) === true;
+                };
+                m.message = "match(" + sinon.functionName(expectation.test) + ")";
+                return m;
+            }
+            var str = [];
+            for (var key in expectation) {
+                if (expectation.hasOwnProperty(key)) {
+                    str.push(key + ": " + expectation[key]);
+                }
+            }
+            m.test = function (actual) {
+                return matchObject(expectation, actual);
+            };
+            m.message = "match(" + str.join(", ") + ")";
+            break;
+        case "number":
+            m.test = function (actual) {
+                return expectation == actual;
+            };
+            break;
+        case "string":
+            m.test = function (actual) {
+                if (typeof actual !== "string") {
+                    return false;
+                }
+                return actual.indexOf(expectation) !== -1;
+            };
+            m.message = "match(\"" + expectation + "\")";
+            break;
+        case "regexp":
+            m.test = function (actual) {
+                if (typeof actual !== "string") {
+                    return false;
+                }
+                return expectation.test(actual);
+            };
+            break;
+        case "function":
+            m.test = expectation;
+            if (message) {
+                m.message = message;
+            } else {
+                m.message = "match(" + sinon.functionName(expectation) + ")";
+            }
+            break;
+        default:
+            m.test = function (actual) {
+              return sinon.deepEqual(expectation, actual);
+            };
+        }
+        if (!m.message) {
+            m.message = "match(" + expectation + ")";
+        }
+        return m;
+    };
+
+    match.isMatcher = isMatcher;
+
+    match.any = match(function () {
+        return true;
+    }, "any");
+
+    match.defined = match(function (actual) {
+        return actual !== null && actual !== undefined;
+    }, "defined");
+
+    match.truthy = match(function (actual) {
+        return !!actual;
+    }, "truthy");
+
+    match.falsy = match(function (actual) {
+        return !actual;
+    }, "falsy");
+
+    match.same = function (expectation) {
+        return match(function (actual) {
+            return expectation === actual;
+        }, "same(" + expectation + ")");
+    };
+
+    match.typeOf = function (type) {
+        assertType(type, "string", "type");
+        return match(function (actual) {
+            return sinon.typeOf(actual) === type;
+        }, "typeOf(\"" + type + "\")");
+    };
+
+    match.instanceOf = function (type) {
+        assertType(type, "function", "type");
+        return match(function (actual) {
+            return actual instanceof type;
+        }, "instanceOf(" + sinon.functionName(type) + ")");
+    };
+
+    function createPropertyMatcher(propertyTest, messagePrefix) {
+        return function (property, value) {
+            assertType(property, "string", "property");
+            var onlyProperty = arguments.length === 1;
+            var message = messagePrefix + "(\"" + property + "\"";
+            if (!onlyProperty) {
+                message += ", " + value;
+            }
+            message += ")";
+            return match(function (actual) {
+                if (actual === undefined || actual === null ||
+                        !propertyTest(actual, property)) {
+                    return false;
+                }
+                return onlyProperty || sinon.deepEqual(value, actual[property]);
+            }, message);
+        };
+    }
+
+    match.has = createPropertyMatcher(function (actual, property) {
+        if (typeof actual === "object") {
+            return property in actual;
+        }
+        return actual[property] !== undefined;
+    }, "has");
+
+    match.hasOwn = createPropertyMatcher(function (actual, property) {
+        return actual.hasOwnProperty(property);
+    }, "hasOwn");
+
+    match.bool = match.typeOf("boolean");
+    match.number = match.typeOf("number");
+    match.string = match.typeOf("string");
+    match.object = match.typeOf("object");
+    match.func = match.typeOf("function");
+    match.array = match.typeOf("array");
+    match.regexp = match.typeOf("regexp");
+    match.date = match.typeOf("date");
+
+    if (commonJSModule) {
+        module.exports = match;
+    } else {
+        sinon.match = match;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+  * @depend ../sinon.js
+  * @depend match.js
+  */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+  * Spy calls
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @author Maximilian Antoni (mail@maxantoni.de)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  * Copyright (c) 2013 Maximilian Antoni
+  */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function throwYieldError(proxy, text, args) {
+        var msg = sinon.functionName(proxy) + text;
+        if (args.length) {
+            msg += " Received [" + slice.call(args).join(", ") + "]";
+        }
+        throw new Error(msg);
+    }
+
+    var slice = Array.prototype.slice;
+
+    var callProto = {
+        calledOn: function calledOn(thisValue) {
+            if (sinon.match && sinon.match.isMatcher(thisValue)) {
+                return thisValue.test(this.thisValue);
+            }
+            return this.thisValue === thisValue;
+        },
+
+        calledWith: function calledWith() {
+            for (var i = 0, l = arguments.length; i < l; i += 1) {
+                if (!sinon.deepEqual(arguments[i], this.args[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        },
+
+        calledWithMatch: function calledWithMatch() {
+            for (var i = 0, l = arguments.length; i < l; i += 1) {
+                var actual = this.args[i];
+                var expectation = arguments[i];
+                if (!sinon.match || !sinon.match(expectation).test(actual)) {
+                    return false;
+                }
+            }
+            return true;
+        },
+
+        calledWithExactly: function calledWithExactly() {
+            return arguments.length == this.args.length &&
+                this.calledWith.apply(this, arguments);
+        },
+
+        notCalledWith: function notCalledWith() {
+            return !this.calledWith.apply(this, arguments);
+        },
+
+        notCalledWithMatch: function notCalledWithMatch() {
+            return !this.calledWithMatch.apply(this, arguments);
+        },
+
+        returned: function returned(value) {
+            return sinon.deepEqual(value, this.returnValue);
+        },
+
+        threw: function threw(error) {
+            if (typeof error === "undefined" || !this.exception) {
+                return !!this.exception;
+            }
+
+            return this.exception === error || this.exception.name === error;
+        },
+
+        calledWithNew: function calledWithNew() {
+            return this.proxy.prototype && this.thisValue instanceof this.proxy;
+        },
+
+        calledBefore: function (other) {
+            return this.callId < other.callId;
+        },
+
+        calledAfter: function (other) {
+            return this.callId > other.callId;
+        },
+
+        callArg: function (pos) {
+            this.args[pos]();
+        },
+
+        callArgOn: function (pos, thisValue) {
+            this.args[pos].apply(thisValue);
+        },
+
+        callArgWith: function (pos) {
+            this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
+        },
+
+        callArgOnWith: function (pos, thisValue) {
+            var args = slice.call(arguments, 2);
+            this.args[pos].apply(thisValue, args);
+        },
+
+        "yield": function () {
+            this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
+        },
+
+        yieldOn: function (thisValue) {
+            var args = this.args;
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (typeof args[i] === "function") {
+                    args[i].apply(thisValue, slice.call(arguments, 1));
+                    return;
+                }
+            }
+            throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
+        },
+
+        yieldTo: function (prop) {
+            this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
+        },
+
+        yieldToOn: function (prop, thisValue) {
+            var args = this.args;
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (args[i] && typeof args[i][prop] === "function") {
+                    args[i][prop].apply(thisValue, slice.call(arguments, 2));
+                    return;
+                }
+            }
+            throwYieldError(this.proxy, " cannot yield to '" + prop +
+                "' since no callback was passed.", args);
+        },
+
+        toString: function () {
+            var callStr = this.proxy.toString() + "(";
+            var args = [];
+
+            for (var i = 0, l = this.args.length; i < l; ++i) {
+                args.push(sinon.format(this.args[i]));
+            }
+
+            callStr = callStr + args.join(", ") + ")";
+
+            if (typeof this.returnValue != "undefined") {
+                callStr += " => " + sinon.format(this.returnValue);
+            }
+
+            if (this.exception) {
+                callStr += " !" + this.exception.name;
+
+                if (this.exception.message) {
+                    callStr += "(" + this.exception.message + ")";
+                }
+            }
+
+            return callStr;
+        }
+    };
+
+    callProto.invokeCallback = callProto.yield;
+
+    function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
+        if (typeof id !== "number") {
+            throw new TypeError("Call id is not a number");
+        }
+        var proxyCall = sinon.create(callProto);
+        proxyCall.proxy = spy;
+        proxyCall.thisValue = thisValue;
+        proxyCall.args = args;
+        proxyCall.returnValue = returnValue;
+        proxyCall.exception = exception;
+        proxyCall.callId = id;
+
+        return proxyCall;
+    }
+    createSpyCall.toString = callProto.toString; // used by mocks
+
+    if (commonJSModule) {
+        module.exports = createSpyCall;
+    } else {
+        sinon.spyCall = createSpyCall;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+
+/**
+  * @depend ../sinon.js
+  * @depend call.js
+  */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+  * Spy functions
+  *
+  * @author Christian Johansen (christian@cjohansen.no)
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+    var push = Array.prototype.push;
+    var slice = Array.prototype.slice;
+    var callId = 0;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function spy(object, property) {
+        if (!property && typeof object == "function") {
+            return spy.create(object);
+        }
+
+        if (!object && !property) {
+            return spy.create(function () { });
+        }
+
+        var method = object[property];
+        return sinon.wrapMethod(object, property, spy.create(method));
+    }
+
+    function matchingFake(fakes, args, strict) {
+        if (!fakes) {
+            return;
+        }
+
+        for (var i = 0, l = fakes.length; i < l; i++) {
+            if (fakes[i].matches(args, strict)) {
+                return fakes[i];
+            }
+        }
+    }
+
+    function incrementCallCount() {
+        this.called = true;
+        this.callCount += 1;
+        this.notCalled = false;
+        this.calledOnce = this.callCount == 1;
+        this.calledTwice = this.callCount == 2;
+        this.calledThrice = this.callCount == 3;
+    }
+
+    function createCallProperties() {
+        this.firstCall = this.getCall(0);
+        this.secondCall = this.getCall(1);
+        this.thirdCall = this.getCall(2);
+        this.lastCall = this.getCall(this.callCount - 1);
+    }
+
+    var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
+    function createProxy(func) {
+        // Retain the function length:
+        var p;
+        if (func.length) {
+            eval("p = (function proxy(" + vars.substring(0, func.length * 2 - 1) +
+                ") { return p.invoke(func, this, slice.call(arguments)); });");
+        }
+        else {
+            p = function proxy() {
+                return p.invoke(func, this, slice.call(arguments));
+            };
+        }
+        return p;
+    }
+
+    var uuid = 0;
+
+    // Public API
+    var spyApi = {
+        reset: function () {
+            this.called = false;
+            this.notCalled = true;
+            this.calledOnce = false;
+            this.calledTwice = false;
+            this.calledThrice = false;
+            this.callCount = 0;
+            this.firstCall = null;
+            this.secondCall = null;
+            this.thirdCall = null;
+            this.lastCall = null;
+            this.args = [];
+            this.returnValues = [];
+            this.thisValues = [];
+            this.exceptions = [];
+            this.callIds = [];
+            if (this.fakes) {
+                for (var i = 0; i < this.fakes.length; i++) {
+                    this.fakes[i].reset();
+                }
+            }
+        },
+
+        create: function create(func) {
+            var name;
+
+            if (typeof func != "function") {
+                func = function () { };
+            } else {
+                name = sinon.functionName(func);
+            }
+
+            var proxy = createProxy(func);
+
+            sinon.extend(proxy, spy);
+            delete proxy.create;
+            sinon.extend(proxy, func);
+
+            proxy.reset();
+            proxy.prototype = func.prototype;
+            proxy.displayName = name || "spy";
+            proxy.toString = sinon.functionToString;
+            proxy._create = sinon.spy.create;
+            proxy.id = "spy#" + uuid++;
+
+            return proxy;
+        },
+
+        invoke: function invoke(func, thisValue, args) {
+            var matching = matchingFake(this.fakes, args);
+            var exception, returnValue;
+
+            incrementCallCount.call(this);
+            push.call(this.thisValues, thisValue);
+            push.call(this.args, args);
+            push.call(this.callIds, callId++);
+
+            try {
+                if (matching) {
+                    returnValue = matching.invoke(func, thisValue, args);
+                } else {
+                    returnValue = (this.func || func).apply(thisValue, args);
+                }
+
+                var thisCall = this.getCall(this.callCount - 1);
+                if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
+                    returnValue = thisValue;
+                }
+            } catch (e) {
+                exception = e;
+            }
+
+            push.call(this.exceptions, exception);
+            push.call(this.returnValues, returnValue);
+
+            createCallProperties.call(this);
+
+            if (exception !== undefined) {
+                throw exception;
+            }
+
+            return returnValue;
+        },
+
+        getCall: function getCall(i) {
+            if (i < 0 || i >= this.callCount) {
+                return null;
+            }
+
+            return sinon.spyCall(this, this.thisValues[i], this.args[i],
+                                    this.returnValues[i], this.exceptions[i],
+                                    this.callIds[i]);
+        },
+
+        getCalls: function () {
+            var calls = [];
+            var i;
+
+            for (i = 0; i < this.callCount; i++) {
+                calls.push(this.getCall(i));
+            }
+
+            return calls;
+        },
+
+        calledBefore: function calledBefore(spyFn) {
+            if (!this.called) {
+                return false;
+            }
+
+            if (!spyFn.called) {
+                return true;
+            }
+
+            return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
+        },
+
+        calledAfter: function calledAfter(spyFn) {
+            if (!this.called || !spyFn.called) {
+                return false;
+            }
+
+            return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
+        },
+
+        withArgs: function () {
+            var args = slice.call(arguments);
+
+            if (this.fakes) {
+                var match = matchingFake(this.fakes, args, true);
+
+                if (match) {
+                    return match;
+                }
+            } else {
+                this.fakes = [];
+            }
+
+            var original = this;
+            var fake = this._create();
+            fake.matchingAguments = args;
+            fake.parent = this;
+            push.call(this.fakes, fake);
+
+            fake.withArgs = function () {
+                return original.withArgs.apply(original, arguments);
+            };
+
+            for (var i = 0; i < this.args.length; i++) {
+                if (fake.matches(this.args[i])) {
+                    incrementCallCount.call(fake);
+                    push.call(fake.thisValues, this.thisValues[i]);
+                    push.call(fake.args, this.args[i]);
+                    push.call(fake.returnValues, this.returnValues[i]);
+                    push.call(fake.exceptions, this.exceptions[i]);
+                    push.call(fake.callIds, this.callIds[i]);
+                }
+            }
+            createCallProperties.call(fake);
+
+            return fake;
+        },
+
+        matches: function (args, strict) {
+            var margs = this.matchingAguments;
+
+            if (margs.length <= args.length &&
+                sinon.deepEqual(margs, args.slice(0, margs.length))) {
+                return !strict || margs.length == args.length;
+            }
+        },
+
+        printf: function (format) {
+            var spy = this;
+            var args = slice.call(arguments, 1);
+            var formatter;
+
+            return (format || "").replace(/%(.)/g, function (match, specifyer) {
+                formatter = spyApi.formatters[specifyer];
+
+                if (typeof formatter == "function") {
+                    return formatter.call(null, spy, args);
+                } else if (!isNaN(parseInt(specifyer, 10))) {
+                    return sinon.format(args[specifyer - 1]);
+                }
+
+                return "%" + specifyer;
+            });
+        }
+    };
+
+    function delegateToCalls(method, matchAny, actual, notCalled) {
+        spyApi[method] = function () {
+            if (!this.called) {
+                if (notCalled) {
+                    return notCalled.apply(this, arguments);
+                }
+                return false;
+            }
+
+            var currentCall;
+            var matches = 0;
+
+            for (var i = 0, l = this.callCount; i < l; i += 1) {
+                currentCall = this.getCall(i);
+
+                if (currentCall[actual || method].apply(currentCall, arguments)) {
+                    matches += 1;
+
+                    if (matchAny) {
+                        return true;
+                    }
+                }
+            }
+
+            return matches === this.callCount;
+        };
+    }
+
+    delegateToCalls("calledOn", true);
+    delegateToCalls("alwaysCalledOn", false, "calledOn");
+    delegateToCalls("calledWith", true);
+    delegateToCalls("calledWithMatch", true);
+    delegateToCalls("alwaysCalledWith", false, "calledWith");
+    delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
+    delegateToCalls("calledWithExactly", true);
+    delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
+    delegateToCalls("neverCalledWith", false, "notCalledWith",
+        function () { return true; });
+    delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch",
+        function () { return true; });
+    delegateToCalls("threw", true);
+    delegateToCalls("alwaysThrew", false, "threw");
+    delegateToCalls("returned", true);
+    delegateToCalls("alwaysReturned", false, "returned");
+    delegateToCalls("calledWithNew", true);
+    delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
+    delegateToCalls("callArg", false, "callArgWith", function () {
+        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+    });
+    spyApi.callArgWith = spyApi.callArg;
+    delegateToCalls("callArgOn", false, "callArgOnWith", function () {
+        throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
+    });
+    spyApi.callArgOnWith = spyApi.callArgOn;
+    delegateToCalls("yield", false, "yield", function () {
+        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+    });
+    // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
+    spyApi.invokeCallback = spyApi.yield;
+    delegateToCalls("yieldOn", false, "yieldOn", function () {
+        throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
+    });
+    delegateToCalls("yieldTo", false, "yieldTo", function (property) {
+        throw new Error(this.toString() + " cannot yield to '" + property +
+            "' since it was not yet invoked.");
+    });
+    delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
+        throw new Error(this.toString() + " cannot yield to '" + property +
+            "' since it was not yet invoked.");
+    });
+
+    spyApi.formatters = {
+        "c": function (spy) {
+            return sinon.timesInWords(spy.callCount);
+        },
+
+        "n": function (spy) {
+            return spy.toString();
+        },
+
+        "C": function (spy) {
+            var calls = [];
+
+            for (var i = 0, l = spy.callCount; i < l; ++i) {
+                var stringifiedCall = "    " + spy.getCall(i).toString();
+                if (/\n/.test(calls[i - 1])) {
+                    stringifiedCall = "\n" + stringifiedCall;
+                }
+                push.call(calls, stringifiedCall);
+            }
+
+            return calls.length > 0 ? "\n" + calls.join("\n") : "";
+        },
+
+        "t": function (spy) {
+            var objects = [];
+
+            for (var i = 0, l = spy.callCount; i < l; ++i) {
+                push.call(objects, sinon.format(spy.thisValues[i]));
+            }
+
+            return objects.join(", ");
+        },
+
+        "*": function (spy, args) {
+            var formatted = [];
+
+            for (var i = 0, l = args.length; i < l; ++i) {
+                push.call(formatted, sinon.format(args[i]));
+            }
+
+            return formatted.join(", ");
+        }
+    };
+
+    sinon.extend(spy, spyApi);
+
+    spy.spyCall = sinon.spyCall;
+
+    if (commonJSModule) {
+        module.exports = spy;
+    } else {
+        sinon.spy = spy;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global module, require, sinon, process, setImmediate, setTimeout*/
+/**
+ * Stub behavior
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Tim Fischbach (mail@timfischbach.de)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    var slice = Array.prototype.slice;
+    var join = Array.prototype.join;
+    var proto;
+
+    var nextTick = (function () {
+        if (typeof process === "object" && typeof process.nextTick === "function") {
+            return process.nextTick;
+        } else if (typeof setImmediate === "function") {
+            return setImmediate;
+        } else {
+            return function (callback) {
+                setTimeout(callback, 0);
+            };
+        }
+    })();
+
+    function throwsException(error, message) {
+        if (typeof error == "string") {
+            this.exception = new Error(message || "");
+            this.exception.name = error;
+        } else if (!error) {
+            this.exception = new Error("Error");
+        } else {
+            this.exception = error;
+        }
+
+        return this;
+    }
+
+    function getCallback(behavior, args) {
+        var callArgAt = behavior.callArgAt;
+
+        if (callArgAt < 0) {
+            var callArgProp = behavior.callArgProp;
+
+            for (var i = 0, l = args.length; i < l; ++i) {
+                if (!callArgProp && typeof args[i] == "function") {
+                    return args[i];
+                }
+
+                if (callArgProp && args[i] &&
+                    typeof args[i][callArgProp] == "function") {
+                    return args[i][callArgProp];
+                }
+            }
+
+            return null;
+        }
+
+        return args[callArgAt];
+    }
+
+    function getCallbackError(behavior, func, args) {
+        if (behavior.callArgAt < 0) {
+            var msg;
+
+            if (behavior.callArgProp) {
+                msg = sinon.functionName(behavior.stub) +
+                    " expected to yield to '" + behavior.callArgProp +
+                    "', but no object with such a property was passed.";
+            } else {
+                msg = sinon.functionName(behavior.stub) +
+                    " expected to yield, but no callback was passed.";
+            }
+
+            if (args.length > 0) {
+                msg += " Received [" + join.call(args, ", ") + "]";
+            }
+
+            return msg;
+        }
+
+        return "argument at index " + behavior.callArgAt + " is not a function: " + func;
+    }
+
+    function callCallback(behavior, args) {
+        if (typeof behavior.callArgAt == "number") {
+            var func = getCallback(behavior, args);
+
+            if (typeof func != "function") {
+                throw new TypeError(getCallbackError(behavior, func, args));
+            }
+
+            if (behavior.callbackAsync) {
+                nextTick(function() {
+                    func.apply(behavior.callbackContext, behavior.callbackArguments);
+                });
+            } else {
+                func.apply(behavior.callbackContext, behavior.callbackArguments);
+            }
+        }
+    }
+
+    proto = {
+        create: function(stub) {
+            var behavior = sinon.extend({}, sinon.behavior);
+            delete behavior.create;
+            behavior.stub = stub;
+
+            return behavior;
+        },
+
+        isPresent: function() {
+            return (typeof this.callArgAt == 'number' ||
+                    this.exception ||
+                    typeof this.returnArgAt == 'number' ||
+                    this.returnThis ||
+                    this.returnValueDefined);
+        },
+
+        invoke: function(context, args) {
+            callCallback(this, args);
+
+            if (this.exception) {
+                throw this.exception;
+            } else if (typeof this.returnArgAt == 'number') {
+                return args[this.returnArgAt];
+            } else if (this.returnThis) {
+                return context;
+            }
+
+            return this.returnValue;
+        },
+
+        onCall: function(index) {
+            return this.stub.onCall(index);
+        },
+
+        onFirstCall: function() {
+            return this.stub.onFirstCall();
+        },
+
+        onSecondCall: function() {
+            return this.stub.onSecondCall();
+        },
+
+        onThirdCall: function() {
+            return this.stub.onThirdCall();
+        },
+
+        withArgs: function(/* arguments */) {
+            throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
+                            'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
+        },
+
+        callsArg: function callsArg(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = [];
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgOn: function callsArgOn(pos, context) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = [];
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgWith: function callsArgWith(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        callsArgOnWith: function callsArgWith(pos, context) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = pos;
+            this.callbackArguments = slice.call(arguments, 2);
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yields: function () {
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 0);
+            this.callbackContext = undefined;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsOn: function (context) {
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = context;
+            this.callArgProp = undefined;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsTo: function (prop) {
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 1);
+            this.callbackContext = undefined;
+            this.callArgProp = prop;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+        yieldsToOn: function (prop, context) {
+            if (typeof context != "object") {
+                throw new TypeError("argument context is not an object");
+            }
+
+            this.callArgAt = -1;
+            this.callbackArguments = slice.call(arguments, 2);
+            this.callbackContext = context;
+            this.callArgProp = prop;
+            this.callbackAsync = false;
+
+            return this;
+        },
+
+
+        "throws": throwsException,
+        throwsException: throwsException,
+
+        returns: function returns(value) {
+            this.returnValue = value;
+            this.returnValueDefined = true;
+
+            return this;
+        },
+
+        returnsArg: function returnsArg(pos) {
+            if (typeof pos != "number") {
+                throw new TypeError("argument index is not number");
+            }
+
+            this.returnArgAt = pos;
+
+            return this;
+        },
+
+        returnsThis: function returnsThis() {
+            this.returnThis = true;
+
+            return this;
+        }
+    };
+
+    // create asynchronous versions of callsArg* and yields* methods
+    for (var method in proto) {
+        // need to avoid creating anotherasync versions of the newly added async methods
+        if (proto.hasOwnProperty(method) &&
+            method.match(/^(callsArg|yields)/) &&
+            !method.match(/Async/)) {
+            proto[method + 'Async'] = (function (syncFnName) {
+                return function () {
+                    var result = this[syncFnName].apply(this, arguments);
+                    this.callbackAsync = true;
+                    return result;
+                };
+            })(method);
+        }
+    }
+
+    if (commonJSModule) {
+        module.exports = proto;
+    } else {
+        sinon.behavior = proto;
+    }
+}(typeof sinon == "object" && sinon || null));
+/**
+ * @depend ../sinon.js
+ * @depend spy.js
+ * @depend behavior.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global module, require, sinon*/
+/**
+ * Stub functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function stub(object, property, func) {
+        if (!!func && typeof func != "function") {
+            throw new TypeError("Custom stub should be function");
+        }
+
+        var wrapper;
+
+        if (func) {
+            wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
+        } else {
+            wrapper = stub.create();
+        }
+
+        if (!object && typeof property === "undefined") {
+            return sinon.stub.create();
+        }
+
+        if (typeof property === "undefined" && typeof object == "object") {
+            for (var prop in object) {
+                if (typeof object[prop] === "function") {
+                    stub(object, prop);
+                }
+            }
+
+            return object;
+        }
+
+        return sinon.wrapMethod(object, property, wrapper);
+    }
+
+    function getDefaultBehavior(stub) {
+        return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
+    }
+
+    function getParentBehaviour(stub) {
+        return (stub.parent && getCurrentBehavior(stub.parent));
+    }
+
+    function getCurrentBehavior(stub) {
+        var behavior = stub.behaviors[stub.callCount - 1];
+        return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
+    }
+
+    var uuid = 0;
+
+    sinon.extend(stub, (function () {
+        var proto = {
+            create: function create() {
+                var functionStub = function () {
+                    return getCurrentBehavior(functionStub).invoke(this, arguments);
+                };
+
+                functionStub.id = "stub#" + uuid++;
+                var orig = functionStub;
+                functionStub = sinon.spy.create(functionStub);
+                functionStub.func = orig;
+
+                sinon.extend(functionStub, stub);
+                functionStub._create = sinon.stub.create;
+                functionStub.displayName = "stub";
+                functionStub.toString = sinon.functionToString;
+
+                functionStub.defaultBehavior = null;
+                functionStub.behaviors = [];
+
+                return functionStub;
+            },
+
+            resetBehavior: function () {
+                var i;
+
+                this.defaultBehavior = null;
+                this.behaviors = [];
+
+                delete this.returnValue;
+                delete this.returnArgAt;
+                this.returnThis = false;
+
+                if (this.fakes) {
+                    for (i = 0; i < this.fakes.length; i++) {
+                        this.fakes[i].resetBehavior();
+                    }
+                }
+            },
+
+            onCall: function(index) {
+                if (!this.behaviors[index]) {
+                    this.behaviors[index] = sinon.behavior.create(this);
+                }
+
+                return this.behaviors[index];
+            },
+
+            onFirstCall: function() {
+                return this.onCall(0);
+            },
+
+            onSecondCall: function() {
+                return this.onCall(1);
+            },
+
+            onThirdCall: function() {
+                return this.onCall(2);
+            }
+        };
+
+        for (var method in sinon.behavior) {
+            if (sinon.behavior.hasOwnProperty(method) &&
+                !proto.hasOwnProperty(method) &&
+                method != 'create' &&
+                method != 'withArgs' &&
+                method != 'invoke') {
+                proto[method] = (function(behaviorMethod) {
+                    return function() {
+                        this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
+                        this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
+                        return this;
+                    };
+                }(method));
+            }
+        }
+
+        return proto;
+    }()));
+
+    if (commonJSModule) {
+        module.exports = stub;
+    } else {
+        sinon.stub = stub;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ */
+/*jslint eqeqeq: false, onevar: false, nomen: false*/
+/*global module, require, sinon*/
+/**
+ * Mock functions.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+    var push = [].push;
+    var match;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    match = sinon.match;
+
+    if (!match && commonJSModule) {
+        match = require("./match");
+    }
+
+    function mock(object) {
+        if (!object) {
+            return sinon.expectation.create("Anonymous mock");
+        }
+
+        return mock.create(object);
+    }
+
+    sinon.mock = mock;
+
+    sinon.extend(mock, (function () {
+        function each(collection, callback) {
+            if (!collection) {
+                return;
+            }
+
+            for (var i = 0, l = collection.length; i < l; i += 1) {
+                callback(collection[i]);
+            }
+        }
+
+        return {
+            create: function create(object) {
+                if (!object) {
+                    throw new TypeError("object is null");
+                }
+
+                var mockObject = sinon.extend({}, mock);
+                mockObject.object = object;
+                delete mockObject.create;
+
+                return mockObject;
+            },
+
+            expects: function expects(method) {
+                if (!method) {
+                    throw new TypeError("method is falsy");
+                }
+
+                if (!this.expectations) {
+                    this.expectations = {};
+                    this.proxies = [];
+                }
+
+                if (!this.expectations[method]) {
+                    this.expectations[method] = [];
+                    var mockObject = this;
+
+                    sinon.wrapMethod(this.object, method, function () {
+                        return mockObject.invokeMethod(method, this, arguments);
+                    });
+
+                    push.call(this.proxies, method);
+                }
+
+                var expectation = sinon.expectation.create(method);
+                push.call(this.expectations[method], expectation);
+
+                return expectation;
+            },
+
+            restore: function restore() {
+                var object = this.object;
+
+                each(this.proxies, function (proxy) {
+                    if (typeof object[proxy].restore == "function") {
+                        object[proxy].restore();
+                    }
+                });
+            },
+
+            verify: function verify() {
+                var expectations = this.expectations || {};
+                var messages = [], met = [];
+
+                each(this.proxies, function (proxy) {
+                    each(expectations[proxy], function (expectation) {
+                        if (!expectation.met()) {
+                            push.call(messages, expectation.toString());
+                        } else {
+                            push.call(met, expectation.toString());
+                        }
+                    });
+                });
+
+                this.restore();
+
+                if (messages.length > 0) {
+                    sinon.expectation.fail(messages.concat(met).join("\n"));
+                } else {
+                    sinon.expectation.pass(messages.concat(met).join("\n"));
+                }
+
+                return true;
+            },
+
+            invokeMethod: function invokeMethod(method, thisValue, args) {
+                var expectations = this.expectations && this.expectations[method];
+                var length = expectations && expectations.length || 0, i;
+
+                for (i = 0; i < length; i += 1) {
+                    if (!expectations[i].met() &&
+                        expectations[i].allowsCall(thisValue, args)) {
+                        return expectations[i].apply(thisValue, args);
+                    }
+                }
+
+                var messages = [], available, exhausted = 0;
+
+                for (i = 0; i < length; i += 1) {
+                    if (expectations[i].allowsCall(thisValue, args)) {
+                        available = available || expectations[i];
+                    } else {
+                        exhausted += 1;
+                    }
+                    push.call(messages, "    " + expectations[i].toString());
+                }
+
+                if (exhausted === 0) {
+                    return available.apply(thisValue, args);
+                }
+
+                messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
+                    proxy: method,
+                    args: args
+                }));
+
+                sinon.expectation.fail(messages.join("\n"));
+            }
+        };
+    }()));
+
+    var times = sinon.timesInWords;
+
+    sinon.expectation = (function () {
+        var slice = Array.prototype.slice;
+        var _invoke = sinon.spy.invoke;
+
+        function callCountInWords(callCount) {
+            if (callCount == 0) {
+                return "never called";
+            } else {
+                return "called " + times(callCount);
+            }
+        }
+
+        function expectedCallCountInWords(expectation) {
+            var min = expectation.minCalls;
+            var max = expectation.maxCalls;
+
+            if (typeof min == "number" && typeof max == "number") {
+                var str = times(min);
+
+                if (min != max) {
+                    str = "at least " + str + " and at most " + times(max);
+                }
+
+                return str;
+            }
+
+            if (typeof min == "number") {
+                return "at least " + times(min);
+            }
+
+            return "at most " + times(max);
+        }
+
+        function receivedMinCalls(expectation) {
+            var hasMinLimit = typeof expectation.minCalls == "number";
+            return !hasMinLimit || expectation.callCount >= expectation.minCalls;
+        }
+
+        function receivedMaxCalls(expectation) {
+            if (typeof expectation.maxCalls != "number") {
+                return false;
+            }
+
+            return expectation.callCount == expectation.maxCalls;
+        }
+
+        function verifyMatcher(possibleMatcher, arg){
+            if (match && match.isMatcher(possibleMatcher)) {
+                return possibleMatcher.test(arg);
+            } else {
+                return true;
+            }
+        }
+
+        return {
+            minCalls: 1,
+            maxCalls: 1,
+
+            create: function create(methodName) {
+                var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
+                delete expectation.create;
+                expectation.method = methodName;
+
+                return expectation;
+            },
+
+            invoke: function invoke(func, thisValue, args) {
+                this.verifyCallAllowed(thisValue, args);
+
+                return _invoke.apply(this, arguments);
+            },
+
+            atLeast: function atLeast(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.maxCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.minCalls = num;
+
+                return this;
+            },
+
+            atMost: function atMost(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not number");
+                }
+
+                if (!this.limitsSet) {
+                    this.minCalls = null;
+                    this.limitsSet = true;
+                }
+
+                this.maxCalls = num;
+
+                return this;
+            },
+
+            never: function never() {
+                return this.exactly(0);
+            },
+
+            once: function once() {
+                return this.exactly(1);
+            },
+
+            twice: function twice() {
+                return this.exactly(2);
+            },
+
+            thrice: function thrice() {
+                return this.exactly(3);
+            },
+
+            exactly: function exactly(num) {
+                if (typeof num != "number") {
+                    throw new TypeError("'" + num + "' is not a number");
+                }
+
+                this.atLeast(num);
+                return this.atMost(num);
+            },
+
+            met: function met() {
+                return !this.failed && receivedMinCalls(this);
+            },
+
+            verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
+                if (receivedMaxCalls(this)) {
+                    this.failed = true;
+                    sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
+                        this.expectedThis);
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return;
+                }
+
+                if (!args) {
+                    sinon.expectation.fail(this.method + " received no arguments, expected " +
+                        sinon.format(this.expectedArguments));
+                }
+
+                if (args.length < this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
+                        "), expected " + sinon.format(this.expectedArguments));
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+
+                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", didn't match " + this.expectedArguments.toString());
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
+                            ", expected " + sinon.format(this.expectedArguments));
+                    }
+                }
+            },
+
+            allowsCall: function allowsCall(thisValue, args) {
+                if (this.met() && receivedMaxCalls(this)) {
+                    return false;
+                }
+
+                if ("expectedThis" in this && this.expectedThis !== thisValue) {
+                    return false;
+                }
+
+                if (!("expectedArguments" in this)) {
+                    return true;
+                }
+
+                args = args || [];
+
+                if (args.length < this.expectedArguments.length) {
+                    return false;
+                }
+
+                if (this.expectsExactArgCount &&
+                    args.length != this.expectedArguments.length) {
+                    return false;
+                }
+
+                for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
+                    if (!verifyMatcher(this.expectedArguments[i],args[i])) {
+                        return false;
+                    }
+
+                    if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
+                        return false;
+                    }
+                }
+
+                return true;
+            },
+
+            withArgs: function withArgs() {
+                this.expectedArguments = slice.call(arguments);
+                return this;
+            },
+
+            withExactArgs: function withExactArgs() {
+                this.withArgs.apply(this, arguments);
+                this.expectsExactArgCount = true;
+                return this;
+            },
+
+            on: function on(thisValue) {
+                this.expectedThis = thisValue;
+                return this;
+            },
+
+            toString: function () {
+                var args = (this.expectedArguments || []).slice();
+
+                if (!this.expectsExactArgCount) {
+                    push.call(args, "[...]");
+                }
+
+                var callStr = sinon.spyCall.toString.call({
+                    proxy: this.method || "anonymous mock expectation",
+                    args: args
+                });
+
+                var message = callStr.replace(", [...", "[, ...") + " " +
+                    expectedCallCountInWords(this);
+
+                if (this.met()) {
+                    return "Expectation met: " + message;
+                }
+
+                return "Expected " + message + " (" +
+                    callCountInWords(this.callCount) + ")";
+            },
+
+            verify: function verify() {
+                if (!this.met()) {
+                    sinon.expectation.fail(this.toString());
+                } else {
+                    sinon.expectation.pass(this.toString());
+                }
+
+                return true;
+            },
+
+            pass: function(message) {
+              sinon.assert.pass(message);
+            },
+            fail: function (message) {
+                var exception = new Error(message);
+                exception.name = "ExpectationError";
+
+                throw exception;
+            }
+        };
+    }());
+
+    if (commonJSModule) {
+        module.exports = mock;
+    } else {
+        sinon.mock = mock;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ * @depend mock.js
+ */
+/*jslint eqeqeq: false, onevar: false, forin: true*/
+/*global module, require, sinon*/
+/**
+ * Collections of stubs, spies and mocks.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+    var push = [].push;
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function getFakes(fakeCollection) {
+        if (!fakeCollection.fakes) {
+            fakeCollection.fakes = [];
+        }
+
+        return fakeCollection.fakes;
+    }
+
+    function each(fakeCollection, method) {
+        var fakes = getFakes(fakeCollection);
+
+        for (var i = 0, l = fakes.length; i < l; i += 1) {
+            if (typeof fakes[i][method] == "function") {
+                fakes[i][method]();
+            }
+        }
+    }
+
+    function compact(fakeCollection) {
+        var fakes = getFakes(fakeCollection);
+        var i = 0;
+        while (i < fakes.length) {
+          fakes.splice(i, 1);
+        }
+    }
+
+    var collection = {
+        verify: function resolve() {
+            each(this, "verify");
+        },
+
+        restore: function restore() {
+            each(this, "restore");
+            compact(this);
+        },
+
+        verifyAndRestore: function verifyAndRestore() {
+            var exception;
+
+            try {
+                this.verify();
+            } catch (e) {
+                exception = e;
+            }
+
+            this.restore();
+
+            if (exception) {
+                throw exception;
+            }
+        },
+
+        add: function add(fake) {
+            push.call(getFakes(this), fake);
+            return fake;
+        },
+
+        spy: function spy() {
+            return this.add(sinon.spy.apply(sinon, arguments));
+        },
+
+        stub: function stub(object, property, value) {
+            if (property) {
+                var original = object[property];
+
+                if (typeof original != "function") {
+                    if (!hasOwnProperty.call(object, property)) {
+                        throw new TypeError("Cannot stub non-existent own property " + property);
+                    }
+
+                    object[property] = value;
+
+                    return this.add({
+                        restore: function () {
+                            object[property] = original;
+                        }
+                    });
+                }
+            }
+            if (!property && !!object && typeof object == "object") {
+                var stubbedObj = sinon.stub.apply(sinon, arguments);
+
+                for (var prop in stubbedObj) {
+                    if (typeof stubbedObj[prop] === "function") {
+                        this.add(stubbedObj[prop]);
+                    }
+                }
+
+                return stubbedObj;
+            }
+
+            return this.add(sinon.stub.apply(sinon, arguments));
+        },
+
+        mock: function mock() {
+            return this.add(sinon.mock.apply(sinon, arguments));
+        },
+
+        inject: function inject(obj) {
+            var col = this;
+
+            obj.spy = function () {
+                return col.spy.apply(col, arguments);
+            };
+
+            obj.stub = function () {
+                return col.stub.apply(col, arguments);
+            };
+
+            obj.mock = function () {
+                return col.mock.apply(col, arguments);
+            };
+
+            return obj;
+        }
+    };
+
+    if (commonJSModule) {
+        module.exports = collection;
+    } else {
+        sinon.collection = collection;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
+/*global module, require, window*/
+/**
+ * Fake timer API
+ * setTimeout
+ * setInterval
+ * clearTimeout
+ * clearInterval
+ * tick
+ * reset
+ * Date
+ *
+ * Inspired by jsUnitMockTimeOut from JsUnit
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+(function (global) {
+    var id = 1;
+
+    function addTimer(args, recurring) {
+        if (args.length === 0) {
+            throw new Error("Function requires at least 1 parameter");
+        }
+
+        if (typeof args[0] === "undefined") {
+            throw new Error("Callback must be provided to timer calls");
+        }
+
+        var toId = id++;
+        var delay = args[1] || 0;
+
+        if (!this.timeouts) {
+            this.timeouts = {};
+        }
+
+        this.timeouts[toId] = {
+            id: toId,
+            func: args[0],
+            callAt: this.now + delay,
+            invokeArgs: Array.prototype.slice.call(args, 2)
+        };
+
+        if (recurring === true) {
+            this.timeouts[toId].interval = delay;
+        }
+
+        return toId;
+    }
+
+    function parseTime(str) {
+        if (!str) {
+            return 0;
+        }
+
+        var strings = str.split(":");
+        var l = strings.length, i = l;
+        var ms = 0, parsed;
+
+        if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
+            throw new Error("tick only understands numbers and 'h:m:s'");
+        }
+
+        while (i--) {
+            parsed = parseInt(strings[i], 10);
+
+            if (parsed >= 60) {
+                throw new Error("Invalid time " + str);
+            }
+
+            ms += parsed * Math.pow(60, (l - i - 1));
+        }
+
+        return ms * 1000;
+    }
+
+    function createObject(object) {
+        var newObject;
+
+        if (Object.create) {
+            newObject = Object.create(object);
+        } else {
+            var F = function () {};
+            F.prototype = object;
+            newObject = new F();
+        }
+
+        newObject.Date.clock = newObject;
+        return newObject;
+    }
+
+    sinon.clock = {
+        now: 0,
+
+        create: function create(now) {
+            var clock = createObject(this);
+
+            if (typeof now == "number") {
+                clock.now = now;
+            }
+
+            if (!!now && typeof now == "object") {
+                throw new TypeError("now should be milliseconds since UNIX epoch");
+            }
+
+            return clock;
+        },
+
+        setTimeout: function setTimeout(callback, timeout) {
+            return addTimer.call(this, arguments, false);
+        },
+
+        clearTimeout: function clearTimeout(timerId) {
+            if (!this.timeouts) {
+                this.timeouts = [];
+            }
+
+            if (timerId in this.timeouts) {
+                delete this.timeouts[timerId];
+            }
+        },
+
+        setInterval: function setInterval(callback, timeout) {
+            return addTimer.call(this, arguments, true);
+        },
+
+        clearInterval: function clearInterval(timerId) {
+            this.clearTimeout(timerId);
+        },
+
+        setImmediate: function setImmediate(callback) {
+            var passThruArgs = Array.prototype.slice.call(arguments, 1);
+
+            return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
+        },
+
+        clearImmediate: function clearImmediate(timerId) {
+            this.clearTimeout(timerId);
+        },
+
+        tick: function tick(ms) {
+            ms = typeof ms == "number" ? ms : parseTime(ms);
+            var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
+            var timer = this.firstTimerInRange(tickFrom, tickTo);
+
+            var firstException;
+            while (timer && tickFrom <= tickTo) {
+                if (this.timeouts[timer.id]) {
+                    tickFrom = this.now = timer.callAt;
+                    try {
+                      this.callTimer(timer);
+                    } catch (e) {
+                      firstException = firstException || e;
+                    }
+                }
+
+                timer = this.firstTimerInRange(previous, tickTo);
+                previous = tickFrom;
+            }
+
+            this.now = tickTo;
+
+            if (firstException) {
+              throw firstException;
+            }
+
+            return this.now;
+        },
+
+        firstTimerInRange: function (from, to) {
+            var timer, smallest = null, originalTimer;
+
+            for (var id in this.timeouts) {
+                if (this.timeouts.hasOwnProperty(id)) {
+                    if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
+                        continue;
+                    }
+
+                    if (smallest === null || this.timeouts[id].callAt < smallest) {
+                        originalTimer = this.timeouts[id];
+                        smallest = this.timeouts[id].callAt;
+
+                        timer = {
+                            func: this.timeouts[id].func,
+                            callAt: this.timeouts[id].callAt,
+                            interval: this.timeouts[id].interval,
+                            id: this.timeouts[id].id,
+                            invokeArgs: this.timeouts[id].invokeArgs
+                        };
+                    }
+                }
+            }
+
+            return timer || null;
+        },
+
+        callTimer: function (timer) {
+            if (typeof timer.interval == "number") {
+                this.timeouts[timer.id].callAt += timer.interval;
+            } else {
+                delete this.timeouts[timer.id];
+            }
+
+            try {
+                if (typeof timer.func == "function") {
+                    timer.func.apply(null, timer.invokeArgs);
+                } else {
+                    eval(timer.func);
+                }
+            } catch (e) {
+              var exception = e;
+            }
+
+            if (!this.timeouts[timer.id]) {
+                if (exception) {
+                  throw exception;
+                }
+                return;
+            }
+
+            if (exception) {
+              throw exception;
+            }
+        },
+
+        reset: function reset() {
+            this.timeouts = {};
+        },
+
+        Date: (function () {
+            var NativeDate = Date;
+
+            function ClockDate(year, month, date, hour, minute, second, ms) {
+                // Defensive and verbose to avoid potential harm in passing
+                // explicit undefined when user does not pass argument
+                switch (arguments.length) {
+                case 0:
+                    return new NativeDate(ClockDate.clock.now);
+                case 1:
+                    return new NativeDate(year);
+                case 2:
+                    return new NativeDate(year, month);
+                case 3:
+                    return new NativeDate(year, month, date);
+                case 4:
+                    return new NativeDate(year, month, date, hour);
+                case 5:
+                    return new NativeDate(year, month, date, hour, minute);
+                case 6:
+                    return new NativeDate(year, month, date, hour, minute, second);
+                default:
+                    return new NativeDate(year, month, date, hour, minute, second, ms);
+                }
+            }
+
+            return mirrorDateProperties(ClockDate, NativeDate);
+        }())
+    };
+
+    function mirrorDateProperties(target, source) {
+        if (source.now) {
+            target.now = function now() {
+                return target.clock.now;
+            };
+        } else {
+            delete target.now;
+        }
+
+        if (source.toSource) {
+            target.toSource = function toSource() {
+                return source.toSource();
+            };
+        } else {
+            delete target.toSource;
+        }
+
+        target.toString = function toString() {
+            return source.toString();
+        };
+
+        target.prototype = source.prototype;
+        target.parse = source.parse;
+        target.UTC = source.UTC;
+        target.prototype.toUTCString = source.prototype.toUTCString;
+
+        for (var prop in source) {
+            if (source.hasOwnProperty(prop)) {
+                target[prop] = source[prop];
+            }
+        }
+
+        return target;
+    }
+
+    var methods = ["Date", "setTimeout", "setInterval",
+                   "clearTimeout", "clearInterval"];
+
+    if (typeof global.setImmediate !== "undefined") {
+        methods.push("setImmediate");
+    }
+
+    if (typeof global.clearImmediate !== "undefined") {
+        methods.push("clearImmediate");
+    }
+
+    function restore() {
+        var method;
+
+        for (var i = 0, l = this.methods.length; i < l; i++) {
+            method = this.methods[i];
+
+            if (global[method].hadOwnProperty) {
+                global[method] = this["_" + method];
+            } else {
+                try {
+                    delete global[method];
+                } catch (e) {}
+            }
+        }
+
+        // Prevent multiple executions which will completely remove these props
+        this.methods = [];
+    }
+
+    function stubGlobal(method, clock) {
+        clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
+        clock["_" + method] = global[method];
+
+        if (method == "Date") {
+            var date = mirrorDateProperties(clock[method], global[method]);
+            global[method] = date;
+        } else {
+            global[method] = function () {
+                return clock[method].apply(clock, arguments);
+            };
+
+            for (var prop in clock[method]) {
+                if (clock[method].hasOwnProperty(prop)) {
+                    global[method][prop] = clock[method][prop];
+                }
+            }
+        }
+
+        global[method].clock = clock;
+    }
+
+    sinon.useFakeTimers = function useFakeTimers(now) {
+        var clock = sinon.clock.create(now);
+        clock.restore = restore;
+        clock.methods = Array.prototype.slice.call(arguments,
+                                                   typeof now == "number" ? 1 : 0);
+
+        if (clock.methods.length === 0) {
+            clock.methods = methods;
+        }
+
+        for (var i = 0, l = clock.methods.length; i < l; i++) {
+            stubGlobal(clock.methods[i], clock);
+        }
+
+        return clock;
+    };
+}(typeof global != "undefined" && typeof global !== "function" ? global : this));
+
+sinon.timers = {
+    setTimeout: setTimeout,
+    clearTimeout: clearTimeout,
+    setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
+    clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
+    setInterval: setInterval,
+    clearInterval: clearInterval,
+    Date: Date
+};
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/*jslint eqeqeq: false, onevar: false*/
+/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
+/**
+ * Minimal Event interface implementation
+ *
+ * Original implementation by Sven Fuchs: https://gist.github.com/995028
+ * Modifications and tests by Christian Johansen.
+ *
+ * @author Sven Fuchs (svenfuchs@artweb-design.de)
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2011 Sven Fuchs, Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    this.sinon = {};
+}
+
+(function () {
+    var push = [].push;
+
+    sinon.Event = function Event(type, bubbles, cancelable, target) {
+        this.initEvent(type, bubbles, cancelable, target);
+    };
+
+    sinon.Event.prototype = {
+        initEvent: function(type, bubbles, cancelable, target) {
+            this.type = type;
+            this.bubbles = bubbles;
+            this.cancelable = cancelable;
+            this.target = target;
+        },
+
+        stopPropagation: function () {},
+
+        preventDefault: function () {
+            this.defaultPrevented = true;
+        }
+    };
+
+    sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
+        this.initEvent(type, false, false, target);
+        this.loaded = progressEventRaw.loaded || null;
+        this.total = progressEventRaw.total || null;
+    };
+
+    sinon.ProgressEvent.prototype = new sinon.Event();
+
+    sinon.ProgressEvent.prototype.constructor =  sinon.ProgressEvent;
+
+    sinon.CustomEvent = function CustomEvent(type, customData, target) {
+        this.initEvent(type, false, false, target);
+        this.detail = customData.detail || null;
+    };
+
+    sinon.CustomEvent.prototype = new sinon.Event();
+
+    sinon.CustomEvent.prototype.constructor =  sinon.CustomEvent;
+
+    sinon.EventTarget = {
+        addEventListener: function addEventListener(event, listener) {
+            this.eventListeners = this.eventListeners || {};
+            this.eventListeners[event] = this.eventListeners[event] || [];
+            push.call(this.eventListeners[event], listener);
+        },
+
+        removeEventListener: function removeEventListener(event, listener) {
+            var listeners = this.eventListeners && this.eventListeners[event] || [];
+
+            for (var i = 0, l = listeners.length; i < l; ++i) {
+                if (listeners[i] == listener) {
+                    return listeners.splice(i, 1);
+                }
+            }
+        },
+
+        dispatchEvent: function dispatchEvent(event) {
+            var type = event.type;
+            var listeners = this.eventListeners && this.eventListeners[type] || [];
+
+            for (var i = 0; i < listeners.length; i++) {
+                if (typeof listeners[i] == "function") {
+                    listeners[i].call(this, event);
+                } else {
+                    listeners[i].handleEvent(event);
+                }
+            }
+
+            return !!event.defaultPrevented;
+        }
+    };
+}());
+
+/**
+ * @depend ../../sinon.js
+ * @depend event.js
+ */
+/*jslint eqeqeq: false, onevar: false*/
+/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
+/**
+ * Fake XMLHttpRequest object
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+// wrapper for global
+(function(global) {
+    if (typeof sinon === "undefined") {
+        global.sinon = {};
+    }
+
+    var supportsProgress = typeof ProgressEvent !== "undefined";
+    var supportsCustomEvent = typeof CustomEvent !== "undefined";
+    sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
+    var xhr = sinon.xhr;
+    xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
+    xhr.GlobalActiveXObject = global.ActiveXObject;
+    xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
+    xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
+    xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
+                                     ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
+    xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
+
+    /*jsl:ignore*/
+    var unsafeHeaders = {
+        "Accept-Charset": true,
+        "Accept-Encoding": true,
+        "Connection": true,
+        "Content-Length": true,
+        "Cookie": true,
+        "Cookie2": true,
+        "Content-Transfer-Encoding": true,
+        "Date": true,
+        "Expect": true,
+        "Host": true,
+        "Keep-Alive": true,
+        "Referer": true,
+        "TE": true,
+        "Trailer": true,
+        "Transfer-Encoding": true,
+        "Upgrade": true,
+        "User-Agent": true,
+        "Via": true
+    };
+    /*jsl:end*/
+
+    function FakeXMLHttpRequest() {
+        this.readyState = FakeXMLHttpRequest.UNSENT;
+        this.requestHeaders = {};
+        this.requestBody = null;
+        this.status = 0;
+        this.statusText = "";
+        this.upload = new UploadProgress();
+        if (sinon.xhr.supportsCORS) {
+            this.withCredentials = false;
+        }
+
+
+        var xhr = this;
+        var events = ["loadstart", "load", "abort", "loadend"];
+
+        function addEventListener(eventName) {
+            xhr.addEventListener(eventName, function (event) {
+                var listener = xhr["on" + eventName];
+
+                if (listener && typeof listener == "function") {
+                    listener.call(this, event);
+                }
+            });
+        }
+
+        for (var i = events.length - 1; i >= 0; i--) {
+            addEventListener(events[i]);
+        }
+
+        if (typeof FakeXMLHttpRequest.onCreate == "function") {
+            FakeXMLHttpRequest.onCreate(this);
+        }
+    }
+
+    // An upload object is created for each
+    // FakeXMLHttpRequest and allows upload
+    // events to be simulated using uploadProgress
+    // and uploadError.
+    function UploadProgress() {
+        this.eventListeners = {
+            "progress": [],
+            "load": [],
+            "abort": [],
+            "error": []
+        }
+    }
+
+    UploadProgress.prototype.addEventListener = function(event, listener) {
+        this.eventListeners[event].push(listener);
+    };
+
+    UploadProgress.prototype.removeEventListener = function(event, listener) {
+        var listeners = this.eventListeners[event] || [];
+
+        for (var i = 0, l = listeners.length; i < l; ++i) {
+            if (listeners[i] == listener) {
+                return listeners.splice(i, 1);
+            }
+        }
+    };
+
+    UploadProgress.prototype.dispatchEvent = function(event) {
+        var listeners = this.eventListeners[event.type] || [];
+
+        for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
+            listener(event);
+        }
+    };
+
+    function verifyState(xhr) {
+        if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+
+        if (xhr.sendFlag) {
+            throw new Error("INVALID_STATE_ERR");
+        }
+    }
+
+    // filtering to enable a white-list version of Sinon FakeXhr,
+    // where whitelisted requests are passed through to real XHR
+    function each(collection, callback) {
+        if (!collection) return;
+        for (var i = 0, l = collection.length; i < l; i += 1) {
+            callback(collection[i]);
+        }
+    }
+    function some(collection, callback) {
+        for (var index = 0; index < collection.length; index++) {
+            if(callback(collection[index]) === true) return true;
+        }
+        return false;
+    }
+    // largest arity in XHR is 5 - XHR#open
+    var apply = function(obj,method,args) {
+        switch(args.length) {
+        case 0: return obj[method]();
+        case 1: return obj[method](args[0]);
+        case 2: return obj[method](args[0],args[1]);
+        case 3: return obj[method](args[0],args[1],args[2]);
+        case 4: return obj[method](args[0],args[1],args[2],args[3]);
+        case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
+        }
+    };
+
+    FakeXMLHttpRequest.filters = [];
+    FakeXMLHttpRequest.addFilter = function(fn) {
+        this.filters.push(fn)
+    };
+    var IE6Re = /MSIE 6/;
+    FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
+        var xhr = new sinon.xhr.workingXHR();
+        each(["open","setRequestHeader","send","abort","getResponseHeader",
+              "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
+             function(method) {
+                 fakeXhr[method] = function() {
+                   return apply(xhr,method,arguments);
+                 };
+             });
+
+        var copyAttrs = function(args) {
+            each(args, function(attr) {
+              try {
+                fakeXhr[attr] = xhr[attr]
+              } catch(e) {
+                if(!IE6Re.test(navigator.userAgent)) throw e;
+              }
+            });
+        };
+
+        var stateChange = function() {
+            fakeXhr.readyState = xhr.readyState;
+            if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                copyAttrs(["status","statusText"]);
+            }
+            if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
+                copyAttrs(["responseText"]);
+            }
+            if(xhr.readyState === FakeXMLHttpRequest.DONE) {
+                copyAttrs(["responseXML"]);
+            }
+            if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
+        };
+        if(xhr.addEventListener) {
+          for(var event in fakeXhr.eventListeners) {
+              if(fakeXhr.eventListeners.hasOwnProperty(event)) {
+                  each(fakeXhr.eventListeners[event],function(handler) {
+                      xhr.addEventListener(event, handler);
+                  });
+              }
+          }
+          xhr.addEventListener("readystatechange",stateChange);
+        } else {
+          xhr.onreadystatechange = stateChange;
+        }
+        apply(xhr,"open",xhrArgs);
+    };
+    FakeXMLHttpRequest.useFilters = false;
+
+    function verifyRequestOpened(xhr) {
+        if (xhr.readyState != FakeXMLHttpRequest.OPENED) {
+            throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
+        }
+    }
+
+    function verifyRequestSent(xhr) {
+        if (xhr.readyState == FakeXMLHttpRequest.DONE) {
+            throw new Error("Request done");
+        }
+    }
+
+    function verifyHeadersReceived(xhr) {
+        if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
+            throw new Error("No headers received");
+        }
+    }
+
+    function verifyResponseBodyType(body) {
+        if (typeof body != "string") {
+            var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
+                                 body + ", which is not a string.");
+            error.name = "InvalidBodyException";
+            throw error;
+        }
+    }
+
+    sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
+        async: true,
+
+        open: function open(method, url, async, username, password) {
+            this.method = method;
+            this.url = url;
+            this.async = typeof async == "boolean" ? async : true;
+            this.username = username;
+            this.password = password;
+            this.responseText = null;
+            this.responseXML = null;
+            this.requestHeaders = {};
+            this.sendFlag = false;
+            if(sinon.FakeXMLHttpRequest.useFilters === true) {
+                var xhrArgs = arguments;
+                var defake = some(FakeXMLHttpRequest.filters,function(filter) {
+                    return filter.apply(this,xhrArgs)
+                });
+                if (defake) {
+                  return sinon.FakeXMLHttpRequest.defake(this,arguments);
+                }
+            }
+            this.readyStateChange(FakeXMLHttpRequest.OPENED);
+        },
+
+        readyStateChange: function readyStateChange(state) {
+            this.readyState = state;
+
+            if (typeof this.onreadystatechange == "function") {
+                try {
+                    this.onreadystatechange();
+                } catch (e) {
+                    sinon.logError("Fake XHR onreadystatechange handler", e);
+                }
+            }
+
+            this.dispatchEvent(new sinon.Event("readystatechange"));
+
+            switch (this.readyState) {
+                case FakeXMLHttpRequest.DONE:
+                    this.dispatchEvent(new sinon.Event("load", false, false, this));
+                    this.dispatchEvent(new sinon.Event("loadend", false, false, this));
+                    this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
+                    if (supportsProgress) {
+                        this.upload.dispatchEvent(new sinon.ProgressEvent('progress', {loaded: 100, total: 100}));
+                    }
+                    break;
+            }
+        },
+
+        setRequestHeader: function setRequestHeader(header, value) {
+            verifyState(this);
+
+            if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
+                throw new Error("Refused to set unsafe header \"" + header + "\"");
+            }
+
+            if (this.requestHeaders[header]) {
+                this.requestHeaders[header] += "," + value;
+            } else {
+                this.requestHeaders[header] = value;
+            }
+        },
+
+        // Helps testing
+        setResponseHeaders: function setResponseHeaders(headers) {
+            verifyRequestOpened(this);
+            this.responseHeaders = {};
+
+            for (var header in headers) {
+                if (headers.hasOwnProperty(header)) {
+                    this.responseHeaders[header] = headers[header];
+                }
+            }
+
+            if (this.async) {
+                this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
+            } else {
+                this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
+            }
+        },
+
+        // Currently treats ALL data as a DOMString (i.e. no Document)
+        send: function send(data) {
+            verifyState(this);
+
+            if (!/^(get|head)$/i.test(this.method)) {
+                if (this.requestHeaders["Content-Type"]) {
+                    var value = this.requestHeaders["Content-Type"].split(";");
+                    this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
+                } else {
+                    this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
+                }
+
+                this.requestBody = data;
+            }
+
+            this.errorFlag = false;
+            this.sendFlag = this.async;
+            this.readyStateChange(FakeXMLHttpRequest.OPENED);
+
+            if (typeof this.onSend == "function") {
+                this.onSend(this);
+            }
+
+            this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
+        },
+
+        abort: function abort() {
+            this.aborted = true;
+            this.responseText = null;
+            this.errorFlag = true;
+            this.requestHeaders = {};
+
+            if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
+                this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
+                this.sendFlag = false;
+            }
+
+            this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
+
+            this.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+            this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
+
+            if (typeof this.onerror === "function") {
+                this.onerror();
+            }
+        },
+
+        getResponseHeader: function getResponseHeader(header) {
+            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                return null;
+            }
+
+            if (/^Set-Cookie2?$/i.test(header)) {
+                return null;
+            }
+
+            header = header.toLowerCase();
+
+            for (var h in this.responseHeaders) {
+                if (h.toLowerCase() == header) {
+                    return this.responseHeaders[h];
+                }
+            }
+
+            return null;
+        },
+
+        getAllResponseHeaders: function getAllResponseHeaders() {
+            if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
+                return "";
+            }
+
+            var headers = "";
+
+            for (var header in this.responseHeaders) {
+                if (this.responseHeaders.hasOwnProperty(header) &&
+                    !/^Set-Cookie2?$/i.test(header)) {
+                    headers += header + ": " + this.responseHeaders[header] + "\r\n";
+                }
+            }
+
+            return headers;
+        },
+
+        setResponseBody: function setResponseBody(body) {
+            verifyRequestSent(this);
+            verifyHeadersReceived(this);
+            verifyResponseBodyType(body);
+
+            var chunkSize = this.chunkSize || 10;
+            var index = 0;
+            this.responseText = "";
+
+            do {
+                if (this.async) {
+                    this.readyStateChange(FakeXMLHttpRequest.LOADING);
+                }
+
+                this.responseText += body.substring(index, index + chunkSize);
+                index += chunkSize;
+            } while (index < body.length);
+
+            var type = this.getResponseHeader("Content-Type");
+
+            if (this.responseText &&
+                (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
+                try {
+                    this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
+                } catch (e) {
+                    // Unable to parse XML - no biggie
+                }
+            }
+
+            if (this.async) {
+                this.readyStateChange(FakeXMLHttpRequest.DONE);
+            } else {
+                this.readyState = FakeXMLHttpRequest.DONE;
+            }
+        },
+
+        respond: function respond(status, headers, body) {
+            this.status = typeof status == "number" ? status : 200;
+            this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
+            this.setResponseHeaders(headers || {});
+            this.setResponseBody(body || "");
+        },
+
+        uploadProgress: function uploadProgress(progressEventRaw) {
+            if (supportsProgress) {
+                this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
+            }
+        },
+
+        uploadError: function uploadError(error) {
+            if (supportsCustomEvent) {
+                this.upload.dispatchEvent(new sinon.CustomEvent("error", {"detail": error}));
+            }
+        }
+    });
+
+    sinon.extend(FakeXMLHttpRequest, {
+        UNSENT: 0,
+        OPENED: 1,
+        HEADERS_RECEIVED: 2,
+        LOADING: 3,
+        DONE: 4
+    });
+
+    // Borrowed from JSpec
+    FakeXMLHttpRequest.parseXML = function parseXML(text) {
+        var xmlDoc;
+
+        if (typeof DOMParser != "undefined") {
+            var parser = new DOMParser();
+            xmlDoc = parser.parseFromString(text, "text/xml");
+        } else {
+            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+            xmlDoc.async = "false";
+            xmlDoc.loadXML(text);
+        }
+
+        return xmlDoc;
+    };
+
+    FakeXMLHttpRequest.statusCodes = {
+        100: "Continue",
+        101: "Switching Protocols",
+        200: "OK",
+        201: "Created",
+        202: "Accepted",
+        203: "Non-Authoritative Information",
+        204: "No Content",
+        205: "Reset Content",
+        206: "Partial Content",
+        300: "Multiple Choice",
+        301: "Moved Permanently",
+        302: "Found",
+        303: "See Other",
+        304: "Not Modified",
+        305: "Use Proxy",
+        307: "Temporary Redirect",
+        400: "Bad Request",
+        401: "Unauthorized",
+        402: "Payment Required",
+        403: "Forbidden",
+        404: "Not Found",
+        405: "Method Not Allowed",
+        406: "Not Acceptable",
+        407: "Proxy Authentication Required",
+        408: "Request Timeout",
+        409: "Conflict",
+        410: "Gone",
+        411: "Length Required",
+        412: "Precondition Failed",
+        413: "Request Entity Too Large",
+        414: "Request-URI Too Long",
+        415: "Unsupported Media Type",
+        416: "Requested Range Not Satisfiable",
+        417: "Expectation Failed",
+        422: "Unprocessable Entity",
+        500: "Internal Server Error",
+        501: "Not Implemented",
+        502: "Bad Gateway",
+        503: "Service Unavailable",
+        504: "Gateway Timeout",
+        505: "HTTP Version Not Supported"
+    };
+
+    sinon.useFakeXMLHttpRequest = function () {
+        sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
+            if (xhr.supportsXHR) {
+                global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
+            }
+
+            if (xhr.supportsActiveX) {
+                global.ActiveXObject = xhr.GlobalActiveXObject;
+            }
+
+            delete sinon.FakeXMLHttpRequest.restore;
+
+            if (keepOnCreate !== true) {
+                delete sinon.FakeXMLHttpRequest.onCreate;
+            }
+        };
+        if (xhr.supportsXHR) {
+            global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
+        }
+
+        if (xhr.supportsActiveX) {
+            global.ActiveXObject = function ActiveXObject(objId) {
+                if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
+
+                    return new sinon.FakeXMLHttpRequest();
+                }
+
+                return new xhr.GlobalActiveXObject(objId);
+            };
+        }
+
+        return sinon.FakeXMLHttpRequest;
+    };
+
+    sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
+
+})(typeof global === "object" ? global : this);
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/**
+ * @depend fake_xml_http_request.js
+ */
+/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
+/*global module, require, window*/
+/**
+ * The Sinon "server" mimics a web server that receives requests from
+ * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
+ * both synchronously and asynchronously. To respond synchronuously, canned
+ * answers have to be provided upfront.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof sinon == "undefined") {
+    var sinon = {};
+}
+
+sinon.fakeServer = (function () {
+    var push = [].push;
+    function F() {}
+
+    function create(proto) {
+        F.prototype = proto;
+        return new F();
+    }
+
+    function responseArray(handler) {
+        var response = handler;
+
+        if (Object.prototype.toString.call(handler) != "[object Array]") {
+            response = [200, {}, handler];
+        }
+
+        if (typeof response[2] != "string") {
+            throw new TypeError("Fake server response body should be string, but was " +
+                                typeof response[2]);
+        }
+
+        return response;
+    }
+
+    var wloc = typeof window !== "undefined" ? window.location : {};
+    var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
+
+    function matchOne(response, reqMethod, reqUrl) {
+        var rmeth = response.method;
+        var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
+        var url = response.url;
+        var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
+
+        return matchMethod && matchUrl;
+    }
+
+    function match(response, request) {
+        var requestUrl = request.url;
+
+        if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
+            requestUrl = requestUrl.replace(rCurrLoc, "");
+        }
+
+        if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
+            if (typeof response.response == "function") {
+                var ru = response.url;
+                var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
+                return response.response.apply(response, args);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    function log(response, request) {
+        var str;
+
+        str =  "Request:\n"  + sinon.format(request)  + "\n\n";
+        str += "Response:\n" + sinon.format(response) + "\n\n";
+
+        sinon.log(str);
+    }
+
+    return {
+        create: function () {
+            var server = create(this);
+            this.xhr = sinon.useFakeXMLHttpRequest();
+            server.requests = [];
+
+            this.xhr.onCreate = function (xhrObj) {
+                server.addRequest(xhrObj);
+            };
+
+            return server;
+        },
+
+        addRequest: function addRequest(xhrObj) {
+            var server = this;
+            push.call(this.requests, xhrObj);
+
+            xhrObj.onSend = function () {
+                server.handleRequest(this);
+
+                if (server.autoRespond && !server.responding) {
+                    setTimeout(function () {
+                        server.responding = false;
+                        server.respond();
+                    }, server.autoRespondAfter || 10);
+
+                    server.responding = true;
+                }
+            };
+        },
+
+        getHTTPMethod: function getHTTPMethod(request) {
+            if (this.fakeHTTPMethods && /post/i.test(request.method)) {
+                var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
+                return !!matches ? matches[1] : request.method;
+            }
+
+            return request.method;
+        },
+
+        handleRequest: function handleRequest(xhr) {
+            if (xhr.async) {
+                if (!this.queue) {
+                    this.queue = [];
+                }
+
+                push.call(this.queue, xhr);
+            } else {
+                this.processRequest(xhr);
+            }
+        },
+
+        respondWith: function respondWith(method, url, body) {
+            if (arguments.length == 1 && typeof method != "function") {
+                this.response = responseArray(method);
+                return;
+            }
+
+            if (!this.responses) { this.responses = []; }
+
+            if (arguments.length == 1) {
+                body = method;
+                url = method = null;
+            }
+
+            if (arguments.length == 2) {
+                body = url;
+                url = method;
+                method = null;
+            }
+
+            push.call(this.responses, {
+                method: method,
+                url: url,
+                response: typeof body == "function" ? body : responseArray(body)
+            });
+        },
+
+        respond: function respond() {
+            if (arguments.length > 0) this.respondWith.apply(this, arguments);
+            var queue = this.queue || [];
+            var requests = queue.splice(0);
+            var request;
+
+            while(request = requests.shift()) {
+                this.processRequest(request);
+            }
+        },
+
+        processRequest: function processRequest(request) {
+            try {
+                if (request.aborted) {
+                    return;
+                }
+
+                var response = this.response || [404, {}, ""];
+
+                if (this.responses) {
+                    for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
+                        if (match.call(this, this.responses[i], request)) {
+                            response = this.responses[i].response;
+                            break;
+                        }
+                    }
+                }
+
+                if (request.readyState != 4) {
+                    log(response, request);
+
+                    request.respond(response[0], response[1], response[2]);
+                }
+            } catch (e) {
+                sinon.logError("Fake server request processing", e);
+            }
+        },
+
+        restore: function restore() {
+            return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
+        }
+    };
+}());
+
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = sinon;
+}
+
+/**
+ * @depend fake_server.js
+ * @depend fake_timers.js
+ */
+/*jslint browser: true, eqeqeq: false, onevar: false*/
+/*global sinon*/
+/**
+ * Add-on for sinon.fakeServer that automatically handles a fake timer along with
+ * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
+ * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
+ * it polls the object for completion with setInterval. Dispite the direct
+ * motivation, there is nothing jQuery-specific in this file, so it can be used
+ * in any environment where the ajax implementation depends on setInterval or
+ * setTimeout.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function () {
+    function Server() {}
+    Server.prototype = sinon.fakeServer;
+
+    sinon.fakeServerWithClock = new Server();
+
+    sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
+        if (xhr.async) {
+            if (typeof setTimeout.clock == "object") {
+                this.clock = setTimeout.clock;
+            } else {
+                this.clock = sinon.useFakeTimers();
+                this.resetClock = true;
+            }
+
+            if (!this.longestTimeout) {
+                var clockSetTimeout = this.clock.setTimeout;
+                var clockSetInterval = this.clock.setInterval;
+                var server = this;
+
+                this.clock.setTimeout = function (fn, timeout) {
+                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                    return clockSetTimeout.apply(this, arguments);
+                };
+
+                this.clock.setInterval = function (fn, timeout) {
+                    server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
+
+                    return clockSetInterval.apply(this, arguments);
+                };
+            }
+        }
+
+        return sinon.fakeServer.addRequest.call(this, xhr);
+    };
+
+    sinon.fakeServerWithClock.respond = function respond() {
+        var returnVal = sinon.fakeServer.respond.apply(this, arguments);
+
+        if (this.clock) {
+            this.clock.tick(this.longestTimeout || 0);
+            this.longestTimeout = 0;
+
+            if (this.resetClock) {
+                this.clock.restore();
+                this.resetClock = false;
+            }
+        }
+
+        return returnVal;
+    };
+
+    sinon.fakeServerWithClock.restore = function restore() {
+        if (this.clock) {
+            this.clock.restore();
+        }
+
+        return sinon.fakeServer.restore.apply(this, arguments);
+    };
+}());
+
+/**
+ * @depend ../sinon.js
+ * @depend collection.js
+ * @depend util/fake_timers.js
+ * @depend util/fake_server_with_clock.js
+ */
+/*jslint eqeqeq: false, onevar: false, plusplus: false*/
+/*global require, module*/
+/**
+ * Manages fake collections as well as fake utilities such as Sinon's
+ * timers and fake XHR implementation in one convenient object.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+if (typeof module !== 'undefined' && module.exports) {
+    var sinon = require("../sinon");
+    sinon.extend(sinon, require("./util/fake_timers"));
+}
+
+(function () {
+    var push = [].push;
+
+    function exposeValue(sandbox, config, key, value) {
+        if (!value) {
+            return;
+        }
+
+        if (config.injectInto && !(key in config.injectInto)) {
+            config.injectInto[key] = value;
+            sandbox.injectedKeys.push(key);
+        } else {
+            push.call(sandbox.args, value);
+        }
+    }
+
+    function prepareSandboxFromConfig(config) {
+        var sandbox = sinon.create(sinon.sandbox);
+
+        if (config.useFakeServer) {
+            if (typeof config.useFakeServer == "object") {
+                sandbox.serverPrototype = config.useFakeServer;
+            }
+
+            sandbox.useFakeServer();
+        }
+
+        if (config.useFakeTimers) {
+            if (typeof config.useFakeTimers == "object") {
+                sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
+            } else {
+                sandbox.useFakeTimers();
+            }
+        }
+
+        return sandbox;
+    }
+
+    sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
+        useFakeTimers: function useFakeTimers() {
+            this.clock = sinon.useFakeTimers.apply(sinon, arguments);
+
+            return this.add(this.clock);
+        },
+
+        serverPrototype: sinon.fakeServer,
+
+        useFakeServer: function useFakeServer() {
+            var proto = this.serverPrototype || sinon.fakeServer;
+
+            if (!proto || !proto.create) {
+                return null;
+            }
+
+            this.server = proto.create();
+            return this.add(this.server);
+        },
+
+        inject: function (obj) {
+            sinon.collection.inject.call(this, obj);
+
+            if (this.clock) {
+                obj.clock = this.clock;
+            }
+
+            if (this.server) {
+                obj.server = this.server;
+                obj.requests = this.server.requests;
+            }
+
+            return obj;
+        },
+
+        restore: function () {
+            sinon.collection.restore.apply(this, arguments);
+            this.restoreContext();
+        },
+
+        restoreContext: function () {
+            if (this.injectedKeys) {
+                for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
+                    delete this.injectInto[this.injectedKeys[i]];
+                }
+                this.injectedKeys = [];
+            }
+        },
+
+        create: function (config) {
+            if (!config) {
+                return sinon.create(sinon.sandbox);
+            }
+
+            var sandbox = prepareSandboxFromConfig(config);
+            sandbox.args = sandbox.args || [];
+            sandbox.injectedKeys = [];
+            sandbox.injectInto = config.injectInto;
+            var prop, value, exposed = sandbox.inject({});
+
+            if (config.properties) {
+                for (var i = 0, l = config.properties.length; i < l; i++) {
+                    prop = config.properties[i];
+                    value = exposed[prop] || prop == "sandbox" && sandbox;
+                    exposeValue(sandbox, config, prop, value);
+                }
+            } else {
+                exposeValue(sandbox, config, "sandbox", value);
+            }
+
+            return sandbox;
+        }
+    });
+
+    sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
+
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = sinon.sandbox;
+    }
+}());
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ * @depend mock.js
+ * @depend sandbox.js
+ */
+/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Test function, sandboxes fakes
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function test(callback) {
+        var type = typeof callback;
+
+        if (type != "function") {
+            throw new TypeError("sinon.test needs to wrap a test function, got " + type);
+        }
+
+        return function () {
+            var config = sinon.getConfig(sinon.config);
+            config.injectInto = config.injectIntoThis && this || config.injectInto;
+            var sandbox = sinon.sandbox.create(config);
+            var exception, result;
+            var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
+
+            try {
+                result = callback.apply(this, args);
+            } catch (e) {
+                exception = e;
+            }
+
+            if (typeof exception !== "undefined") {
+                sandbox.restore();
+                throw exception;
+            }
+            else {
+                sandbox.verifyAndRestore();
+            }
+
+            return result;
+        };
+    }
+
+    test.config = {
+        injectIntoThis: true,
+        injectInto: null,
+        properties: ["spy", "stub", "mock", "clock", "server", "requests"],
+        useFakeTimers: true,
+        useFakeServer: true
+    };
+
+    if (commonJSModule) {
+        module.exports = test;
+    } else {
+        sinon.test = test;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend test.js
+ */
+/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
+/*global module, require, sinon*/
+/**
+ * Test case, sandboxes all test functions
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon) {
+    var commonJSModule = typeof module !== 'undefined' && module.exports;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon || !Object.prototype.hasOwnProperty) {
+        return;
+    }
+
+    function createTest(property, setUp, tearDown) {
+        return function () {
+            if (setUp) {
+                setUp.apply(this, arguments);
+            }
+
+            var exception, result;
+
+            try {
+                result = property.apply(this, arguments);
+            } catch (e) {
+                exception = e;
+            }
+
+            if (tearDown) {
+                tearDown.apply(this, arguments);
+            }
+
+            if (exception) {
+                throw exception;
+            }
+
+            return result;
+        };
+    }
+
+    function testCase(tests, prefix) {
+        /*jsl:ignore*/
+        if (!tests || typeof tests != "object") {
+            throw new TypeError("sinon.testCase needs an object with test functions");
+        }
+        /*jsl:end*/
+
+        prefix = prefix || "test";
+        var rPrefix = new RegExp("^" + prefix);
+        var methods = {}, testName, property, method;
+        var setUp = tests.setUp;
+        var tearDown = tests.tearDown;
+
+        for (testName in tests) {
+            if (tests.hasOwnProperty(testName)) {
+                property = tests[testName];
+
+                if (/^(setUp|tearDown)$/.test(testName)) {
+                    continue;
+                }
+
+                if (typeof property == "function" && rPrefix.test(testName)) {
+                    method = property;
+
+                    if (setUp || tearDown) {
+                        method = createTest(property, setUp, tearDown);
+                    }
+
+                    methods[testName] = sinon.test(method);
+                } else {
+                    methods[testName] = tests[testName];
+                }
+            }
+        }
+
+        return methods;
+    }
+
+    if (commonJSModule) {
+        module.exports = testCase;
+    } else {
+        sinon.testCase = testCase;
+    }
+}(typeof sinon == "object" && sinon || null));
+
+/**
+ * @depend ../sinon.js
+ * @depend stub.js
+ */
+/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
+/*global module, require, sinon*/
+/**
+ * Assertions matching the test spy retrieval interface.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+
+(function (sinon, global) {
+    var commonJSModule = typeof module !== "undefined" && module.exports;
+    var slice = Array.prototype.slice;
+    var assert;
+
+    if (!sinon && commonJSModule) {
+        sinon = require("../sinon");
+    }
+
+    if (!sinon) {
+        return;
+    }
+
+    function verifyIsStub() {
+        var method;
+
+        for (var i = 0, l = arguments.length; i < l; ++i) {
+            method = arguments[i];
+
+            if (!method) {
+                assert.fail("fake is not a spy");
+            }
+
+            if (typeof method != "function") {
+                assert.fail(method + " is not a function");
+            }
+
+            if (typeof method.getCall != "function") {
+                assert.fail(method + " is not stubbed");
+            }
+        }
+    }
+
+    function failAssertion(object, msg) {
+        object = object || global;
+        var failMethod = object.fail || assert.fail;
+        failMethod.call(object, msg);
+    }
+
+    function mirrorPropAsAssertion(name, method, message) {
+        if (arguments.length == 2) {
+            message = method;
+            method = name;
+        }
+
+        assert[name] = function (fake) {
+            verifyIsStub(fake);
+
+            var args = slice.call(arguments, 1);
+            var failed = false;
+
+            if (typeof method == "function") {
+                failed = !method(fake);
+            } else {
+                failed = typeof fake[method] == "function" ?
+                    !fake[method].apply(fake, args) : !fake[method];
+            }
+
+            if (failed) {
+                failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
+            } else {
+                assert.pass(name);
+            }
+        };
+    }
+
+    function exposedName(prefix, prop) {
+        return !prefix || /^fail/.test(prop) ? prop :
+            prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
+    }
+
+    assert = {
+        failException: "AssertError",
+
+        fail: function fail(message) {
+            var error = new Error(message);
+            error.name = this.failException || assert.failException;
+
+            throw error;
+        },
+
+        pass: function pass(assertion) {},
+
+        callOrder: function assertCallOrder() {
+            verifyIsStub.apply(null, arguments);
+            var expected = "", actual = "";
+
+            if (!sinon.calledInOrder(arguments)) {
+                try {
+                    expected = [].join.call(arguments, ", ");
+                    var calls = slice.call(arguments);
+                    var i = calls.length;
+                    while (i) {
+                        if (!calls[--i].called) {
+                            calls.splice(i, 1);
+                        }
+                    }
+                    actual = sinon.orderByFirstCall(calls).join(", ");
+                } catch (e) {
+                    // If this fails, we'll just fall back to the blank string
+                }
+
+                failAssertion(this, "expected " + expected + " to be " +
+                              "called in order but were called as " + actual);
+            } else {
+                assert.pass("callOrder");
+            }
+        },
+
+        callCount: function assertCallCount(method, count) {
+            verifyIsStub(method);
+
+            if (method.callCount != count) {
+                var msg = "expected %n to be called " + sinon.timesInWords(count) +
+                    " but was called %c%C";
+                failAssertion(this, method.printf(msg));
+            } else {
+                assert.pass("callCount");
+            }
+        },
+
+        expose: function expose(target, options) {
+            if (!target) {
+                throw new TypeError("target is null or undefined");
+            }
+
+            var o = options || {};
+            var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
+            var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
+
+            for (var method in this) {
+                if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
+                    target[exposedName(prefix, method)] = this[method];
+                }
+            }
+
+            return target;
+        },
+
+        match: function match(actual, expectation) {
+            var matcher = sinon.match(expectation);
+            if (matcher.test(actual)) {
+                assert.pass("match");
+            } else {
+                var formatted = [
+                    "expected value to match",
+                    "    expected = " + sinon.format(expectation),
+                    "    actual = " + sinon.format(actual)
+                ]
+                failAssertion(this, formatted.join("\n"));
+            }
+        }
+    };
+
+    mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
+    mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
+                          "expected %n to not have been called but was called %c%C");
+    mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
+    mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
+    mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
+    mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
+    mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
+    mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
+    mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
+    mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
+    mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
+    mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
+    mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
+    mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
+    mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
+    mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
+    mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
+    mirrorPropAsAssertion("threw", "%n did not throw exception%C");
+    mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
+
+    if (commonJSModule) {
+        module.exports = assert;
+    } else {
+        sinon.assert = assert;
+    }
+}(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : (typeof self != "undefined") ? self : global));
+
+return sinon;}.call(typeof window != 'undefined' && window || {}));
diff --git a/resources/sinonjs/sinon-ie-1.8.1.js b/resources/sinonjs/sinon-ie-1.8.1.js
deleted file mode 100644 (file)
index f92e9db..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Sinon.JS 1.8.1, 2014/02/02
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
- *
- * (The BSD License)
- * 
- * Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 
- *     * Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright notice,
- *       this list of conditions and the following disclaimer in the documentation
- *       and/or other materials provided with the distribution.
- *     * Neither the name of Christian Johansen nor the names of his contributors
- *       may be used to endorse or promote products derived from this software
- *       without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
-/**
- * Helps IE run the fake timers. By defining global functions, IE allows
- * them to be overwritten at a later point. If these are not defined like
- * this, overwriting them will result in anything from an exception to browser
- * crash.
- *
- * If you don't require fake timers to work in IE, don't include this file.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-function setTimeout() {}
-function clearTimeout() {}
-function setImmediate() {}
-function clearImmediate() {}
-function setInterval() {}
-function clearInterval() {}
-function Date() {}
-
-// Reassign the original functions. Now their writable attribute
-// should be true. Hackish, I know, but it works.
-setTimeout = sinon.timers.setTimeout;
-clearTimeout = sinon.timers.clearTimeout;
-setImmediate = sinon.timers.setImmediate;
-clearImmediate = sinon.timers.clearImmediate;
-setInterval = sinon.timers.setInterval;
-clearInterval = sinon.timers.clearInterval;
-Date = sinon.timers.Date;
-
-/*global sinon*/
-/**
- * Helps IE run the fake XMLHttpRequest. By defining global functions, IE allows
- * them to be overwritten at a later point. If these are not defined like
- * this, overwriting them will result in anything from an exception to browser
- * crash.
- *
- * If you don't require fake XHR to work in IE, don't include this file.
- *
- * @author Christian Johansen (christian@cjohansen.no)
- * @license BSD
- *
- * Copyright (c) 2010-2013 Christian Johansen
- */
-function XMLHttpRequest() {}
-
-// Reassign the original function. Now its writable attribute
-// should be true. Hackish, I know, but it works.
-XMLHttpRequest = sinon.xhr.XMLHttpRequest || undefined;
diff --git a/resources/sinonjs/sinon-ie-1.9.0.js b/resources/sinonjs/sinon-ie-1.9.0.js
new file mode 100644 (file)
index 0000000..c9fbd9d
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * Sinon.JS 1.9.0, 2014/03/05
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
+ *
+ * (The BSD License)
+ * 
+ * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of Christian Johansen nor the names of his contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
+/**
+ * Helps IE run the fake timers. By defining global functions, IE allows
+ * them to be overwritten at a later point. If these are not defined like
+ * this, overwriting them will result in anything from an exception to browser
+ * crash.
+ *
+ * If you don't require fake timers to work in IE, don't include this file.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+function setTimeout() {}
+function clearTimeout() {}
+function setImmediate() {}
+function clearImmediate() {}
+function setInterval() {}
+function clearInterval() {}
+function Date() {}
+
+// Reassign the original functions. Now their writable attribute
+// should be true. Hackish, I know, but it works.
+setTimeout = sinon.timers.setTimeout;
+clearTimeout = sinon.timers.clearTimeout;
+setImmediate = sinon.timers.setImmediate;
+clearImmediate = sinon.timers.clearImmediate;
+setInterval = sinon.timers.setInterval;
+clearInterval = sinon.timers.clearInterval;
+Date = sinon.timers.Date;
+
+/*global sinon*/
+/**
+ * Helps IE run the fake XMLHttpRequest. By defining global functions, IE allows
+ * them to be overwritten at a later point. If these are not defined like
+ * this, overwriting them will result in anything from an exception to browser
+ * crash.
+ *
+ * If you don't require fake XHR to work in IE, don't include this file.
+ *
+ * @author Christian Johansen (christian@cjohansen.no)
+ * @license BSD
+ *
+ * Copyright (c) 2010-2013 Christian Johansen
+ */
+function XMLHttpRequest() {}
+
+// Reassign the original function. Now its writable attribute
+// should be true. Hackish, I know, but it works.
+XMLHttpRequest = sinon.xhr.XMLHttpRequest || undefined;
index 365995d..46c3030 100644 (file)
@@ -111,41 +111,3 @@ div#simpleSearch {
                z-index: 1;
        }
 }
-
-// The following styles exist only for backwards-compatibility with
-// cached HTML and are to be removed before 1.23 release.
-
-/* Fix direction changed for awful hacks */
-.sitedir-ltr div#simpleSearch button#searchButton {
-       /* @noflip */
-       direction: ltr;
-}
-.sitedir-rtl div#simpleSearch button#searchButton {
-       /* @noflip */
-       direction: rtl;
-}
-
-div#simpleSearch button#searchButton {
-       position: absolute;
-       padding: 0;
-       padding-top: 0.3em;
-       padding-bottom: 0.2em;
-       padding-right: 0.4em;
-       margin: 0;
-       border: none;
-       background-color: transparent;
-       background-image: none;
-       text-indent: 0;
-
-       /* OVERRIDDEN BY COMPLIANT BROWSERS */
-       img {
-               border: none;
-               margin: 0;
-               margin-top: -3px;
-               padding: 0;
-       }
-       /* IGNORED BY IE6 */
-       > img {
-               margin: 0;
-       }
-}
index ea4b0f6..7a048bf 100644 (file)
@@ -40,6 +40,9 @@ $wgAutoloadClasses += array(
        'MediaWikiPHPUnitCommand' => "$testDir/phpunit/MediaWikiPHPUnitCommand.php",
        'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php",
        'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php",
+       'ResourceLoaderTestCase' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+       'ResourceLoaderTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+       'ResourceLoaderFileModuleTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
        'TestUser' => "$testDir/phpunit/includes/TestUser.php",
 
        # tests/phpunit/includes
index 02863c8..bbfea6a 100644 (file)
@@ -1657,7 +1657,7 @@ parsoid
 !!input
 <p><pre>foo</pre></p>
 !!result
-<p data-parsoid='{"stx":"html","autoInsertedEnd":true,"dsr":[0,3,3,0]}'></p><pre data-parsoid='{"stx":"html","dsr":[3,17,5,6]}'>foo</pre><p data-parsoid='{"autoInsertedStart":true,"stx":"html","dsr":[17,21,0,null]}'></p>
+<p data-parsoid='{"stx":"html","autoInsertedEnd":true}'></p><pre data-parsoid='{"stx":"html"}'>foo</pre><p data-parsoid='{"autoInsertedStart":true,"stx":"html"}'></p>
 !!end
 
 !!test
@@ -2156,7 +2156,7 @@ c
 !!end
 
 !!test
-3c. Indent-Pre and block tags (multi-line html)
+3b. Indent-Pre and block tags (multi-line html)
 !!input
  a <span>foo</span>
  b <div> foo </div>
@@ -2168,7 +2168,7 @@ c
 !!end
 
 !!test
-3b. Indent-Pre and block tags (pre-content on separate line)
+3c. Indent-Pre and block tags (pre-content on separate line)
 !!input
 <p>
  foo
@@ -2231,6 +2231,78 @@ foo
 
 !!end
 
+!!test
+4. Indent-Pre and extension tags
+!!input
+ a <gallery>
+File:foobar.jpg
+</gallery>
+!!result
+ a <ul class="gallery mw-gallery-traditional">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+
+!!end
+
+!! test
+Leading pipes outside of tables
+!! options
+parsoid
+!! input
+| foo
+!! result
+<p>| foo</p>
+!! end
+
+!! test
+Leading pipes outside of tables 2
+!! options
+parsoid
+!! input
+a
+| foo
+b
+!! result
+<p>a
+| foo
+b</p>
+!! end
+
+!! test
+Leading pipes outside of tables 3
+!! options
+parsoid
+!! input
+a
+| class="foo bar" | baz
+b
+!! result
+<p>a
+| class="foo bar" | baz
+b</p>
+!! end
+
+!!test
+Render paragraphs when indent-pre is suppressed in blocklevels
+!!input
+<blockquote>
+ foo
+
+ bar
+</blockquote>
+!! result
+<blockquote>
+<p> foo
+</p><p> bar
+</p>
+</blockquote>
+
+!!end
+
 !!test
 4. Multiple spaces at start-of-line
 !!input
@@ -4153,9 +4225,9 @@ parsoid
 
 (http://example.com<!-- hi -->)
 !! result
-<p>(<a data-mw='{"attribs":[[{"txt":"href"},{"html":"http://example.com/&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;hi&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[20,31,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">hi&lt;/span>"}]]}' typeof="mw:ExpandedAttrs" about="#mwt2" rel="mw:ExtLink" href="http://example.com/hi" data-parsoid='{"stx":"url","a":{"href":"http://example.com/hi"},"sa":{"href":"http://example.com/{{echo|hi}}"},"dsr":[1,31,0,0]}'>http://example.com/hi</a>)</p>
+<p>(<a data-mw='{"attribs":[[{"txt":"href"},{"html":"http://example.com/&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;hi&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[20,31,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">hi&lt;/span>"}]]}' typeof="mw:ExpandedAttrs" about="#mwt2" rel="mw:ExtLink" href="http://example.com/hi" data-parsoid='{"stx":"url","a":{"href":"http://example.com/hi"},"sa":{"href":"http://example.com/{{echo|hi}}"}}'>http://example.com/hi</a>)</p>
 
-<p>(<a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url","a":{"href":"http://example.com"},"sa":{"href":"http://example.com&lt;!-- hi -->"},"dsr":[35,64,0,0]}'>http://example.com</a>)</p>
+<p>(<a rel="mw:ExtLink" href="http://example.com" data-parsoid='{"stx":"url","a":{"href":"http://example.com"},"sa":{"href":"http://example.com&lt;!-- hi -->"}}'>http://example.com</a>)</p>
 !! end
 
 ###
@@ -5174,9 +5246,18 @@ Link with HTML entity in suffix / tail
 !! test
 Link with 3 brackets
 !! input
-[[[main page]]]
+[[[Main Page]]]
+!! result
+<p>[[[Main Page]]]
+</p>
+!! end
+
+!! test
+Link with 4 brackets
+!! input
+[[[[Main Page]]]]
 !! result
-<p>[[[main page]]]
+<p>[[<a href="/wiki/Main_Page" title="Main Page">Main Page</a>]]
 </p>
 !! end
 
@@ -5599,6 +5680,36 @@ language=kaa
 </p>
 !! end
 
+!! test
+1. Interaction of linktrail and template encapsulation
+!! options
+parsoid
+!! input
+{{echo|[[Foo]]}}l
+!! result
+<p><a rel="mw:WikiLink" href="Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Foo]]"}},"i":0}},"l"]}'>Fool</a></p>
+!! end
+
+!! test
+2. Interaction of linktrail and template encapsulation
+!! options
+parsoid
+!! input
+{{echo|Some [[Fool]]}}s
+!! result
+<p data-parsoid='{}'><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Some [[Fool]]"}},"i":0}},"s"]}' data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}'>Some </span><a rel="mw:WikiLink" href="./Fool" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Fool"},"sa":{"href":"Fool"},"tail":"s"}'>Fools</a></p>
+!! end
+
+!! test
+3. Interaction of linktrail and template encapsulation
+!! options
+parsoid
+!! input
+{{echo|Some [[Fool]]s are '''bold and foolish'''}}
+!! result
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Some [[Fool]]s are &#39;&#39;&#39;bold and foolish&#39;&#39;&#39;"}},"i":0}}]}' data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]}]]}'>Some <a rel="mw:WikiLink" href="./Fool" data-parsoid='{"stx":"simple","a":{"href":"./Fool"},"sa":{"href":"Fool"},"tail":"s"}'>Fools</a> are <b data-parsoid="{}">bold and foolish</b></p>
+!! end
+
 !! article
 Söfnuður
 !! text
@@ -5687,7 +5798,7 @@ parsoid
 !! input
 [[Foo|{{echo|a}} b {{echo|c}}]]
 !! result
-<p data-parsoid='{"dsr":[0,20,0,0]}'><a rel="mw:WikiLink" href="Foo"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}}]}'>a</span> b <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"c"}},"i":0}}]}'>c</span></a></p>
+<p><a rel="mw:WikiLink" href="Foo"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}}]}'>a</span> b <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"c"}},"i":0}}]}'>c</span></a></p>
 !! end
 
 ###
@@ -5746,10 +5857,9 @@ parsoid
 
 [[:en:Foo]]
 !! result
-<p data-parsoid='{"dsr":[0,17,0,0]}'><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"stx":"simple","a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"wikipedia:Foo"},"isIW":true,"dsr":[0,17,null,1]}'>wikipedia:Foo</a></p>
-
+<p><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"stx":"simple","a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"wikipedia:Foo"},"isIW":true}'>wikipedia:Foo</a></p>
 
-<p data-parsoid='{"dsr":[19,30,0,0]}'><a rel="mw:ExtLink" href="//en.wikipedia.org/wiki/Foo" data-parsoid='{"stx":"simple","a":{"href":"//en.wikipedia.org/wiki/Foo"},"sa":{"href":":en:Foo"},"isIW":true,"dsr":[19,30,null,1]}'>en:Foo</a></p>
+<p><a rel="mw:ExtLink" href="//en.wikipedia.org/wiki/Foo" data-parsoid='{"stx":"simple","a":{"href":"//en.wikipedia.org/wiki/Foo"},"sa":{"href":":en:Foo"},"isIW":true}'>en:Foo</a></p>
 !! end
 
 !! test
@@ -5771,6 +5881,15 @@ parsoid
 <a rel="mw:ExtLink" href="http://de.wikipedia.org/wiki/#foo">is just fragment</a></p>
 !! end
 
+!! test
+Interwiki links: trail
+!! options
+parsoid
+!! input
+[[wikipedia:Foo|Ba]]r
+!! result
+<p data-parsoid='{}'><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"stx":"piped","a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"wikipedia:Foo"},"isIW":true,"tail":"r"}'>Bar</a></p>
+!! end
 
 ###
 ### Interlanguage links
@@ -5856,10 +5975,9 @@ parsoid
 
 [[constructor:foo]]
 !! result
-<p data-parsoid="{&quot;dsr&quot;:[0,15,0,0]}"><a rel="mw:WikiLink" href="./Constructor" data-parsoid="{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Constructor&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;constructor&quot;},&quot;dsr&quot;:[0,15,2,2]}">constructor</a></p>
+<p><a rel="mw:WikiLink" href="./Constructor" data-parsoid="{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Constructor&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;constructor&quot;}}">constructor</a></p>
 
-
-<p data-parsoid="{&quot;dsr&quot;:[17,36,0,0]}"><a rel="mw:WikiLink" href="./Foo" data-parsoid="{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Foo&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;constructor:foo&quot;},&quot;dsr&quot;:[17,36,2,2]}">constructor:foo</a></p>
+<p><a rel="mw:WikiLink" href="./Foo" data-parsoid="{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Foo&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;constructor:foo&quot;}}">constructor:foo</a></p>
 !! end
 
 !! test
@@ -5883,11 +6001,21 @@ parsoid
 <p><a rel="mw:ExtLink" href="//ko.wikipedia.org/wiki/">ko:</a></p>
 !! end
 
+!! test
+Parsoid: Bug #45209, handle interwiki links pointing to the current wiki as plain wiki links
+!! options
+parsoid
+!! input
+[[en:Foo]]
+!! result
+<p><a rel="mw:WikiLink" href="./Foo" data-parsoid='{"stx":"simple","a":{"href":"./Foo"},"sa":{"href":"en:Foo"}}'>Foo</a></p>
+!! end
+
 ###
 ### Redirects, Parsoid-only
 ###
 !! test
-Simple redirect to page
+1. Simple redirect to page
 !! options
 parsoid
 !! input
@@ -5896,6 +6024,19 @@ parsoid
 <link rel="mw:PageProp/redirect" href="./Main_Page">
 !! end
 
+# Only wt2html and html2html since "Main_Page" will serialize to "Main Page"
+!! test
+2. Other redirect variants
+!! options
+parsoid=wt2html,wt2wt
+!! input
+#REDIRECT [[Main_Page]]
+#REDIRECT [[<nowiki>[[Bar]]</nowiki>]]
+!! result
+<link rel="mw:PageProp/redirect" href="./Main_Page">
+<link rel="mw:PageProp/redirect" href="./%5B%5BBar%5D%5D">
+!! end
+
 !! test
 Optional colon in #REDIRECT
 !! options
@@ -6017,6 +6158,17 @@ language=is
 <link rel="mw:PageProp/redirect" href="./Main_Page">
 !! end
 
+!! test
+New redirect
+!! options
+parsoid=html2wt
+!! input
+Foo
+#REDIRECT [[Foo]]
+!! result
+<p>Foo<link rel="mw:PageProp/redirect" href="./Foo"></p>
+!! end
+
 ##
 ## XHTML tidiness
 ###
@@ -7513,6 +7665,39 @@ hi+world%3F%21
 </p>
 !! end
 
+!! test
+Magic Word: prioritize type info over data-parsoid
+!! options
+parsoid=html2wt
+!! input
+__FORCETOC__
+!! result
+<meta property="mw:PageProp/forcetoc" data-parsoid='{"src":"__NOTOC__","magicSrc":"__NOTOC__"}'/>
+!! end
+
+!! test
+Magic Word: serialize on separate line (parsoid)
+!! options
+parsoid=wt2wt,html2wt
+!! input
+foo
+__NOTOC__
+bar
+!! result
+foo<meta property="mw:PageProp/notoc"/>bar
+!! end
+
+!! test
+Magic Word: rt non-english wikis
+!! options
+parsoid=wt2wt
+language=de
+!! input
+__NOEDITSECTION__
+!! result
+<meta property="mw:PageProp/noeditsection" data-parsoid='{"src":"__NOEDITSECTION__","magicSrc":"__NOEDITSECTION__"}'/>
+!! end
+
 ###
 ### Magic links
 ###
@@ -7583,6 +7768,27 @@ Template with invalid target containing unclosed tag
 </p>
 !! end
 
+!! test
+Template with invalid target containing wikilink (php)
+!! options
+php
+!! input
+{{[[Main Page]]}}
+!! result
+<p>{{<a href="/wiki/Main_Page" title="Main Page">Main Page</a>}}
+</p>
+!! end
+
+!! test
+Template with invalid target containing wikilink (parsoid)
+!! options
+parsoid
+!! input
+{{[[Main Page]]}}
+!! result
+<p><span typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":[{"template":{"target":{"wt":"[[Main Page]]"},"params":{},"i":0}}]}'>{{</span><a rel="mw:WikiLink" href="./Main_Page" about="#mwt1">Main Page</a><span about="#mwt1">}}</span></p>
+!! end
+
 !! article
 Template:test
 !! text
@@ -8874,8 +9080,8 @@ parsoid
 <tbody>
 <tr>
 <td>foo</td></tr></tbody></table><span about="#mwt1">
-</span><span about="#mwt1">bar</span><span about="#mwt1">
-</span>
+</span><span about="#mwt1">|bar</span><span about="#mwt1">
+|}</span>
 !!end
 
 !!test
@@ -9767,6 +9973,31 @@ parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption page=stuff</figcaption></figure>
 !! end
 
+!! test
+Allow empty links in image captions (Bug 60753) (parsoid)
+!! options
+parsoid
+!!input
+[[File:Foobar.jpg|thumb|Caption [[Link1]]
+[[]]
+[[Link2]]
+]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption [[Link1]]\n[[]]\n[[Link2]]\n"}],"dsr":[0,59,2,2]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"dsr":[2,null,null,null]}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption data-parsoid='{"dsr":[null,57,null,null]}'>Caption <a rel="mw:WikiLink" href="./Link1" data-parsoid='{"stx":"simple","a":{"href":"./Link1"},"sa":{"href":"Link1"},"dsr":[32,41,2,2]}'>Link1</a>
+[[]]
+<a rel="mw:WikiLink" href="./Link2" data-parsoid='{"stx":"simple","a":{"href":"./Link2"},"sa":{"href":"Link2"},"dsr":[47,56,2,2]}'>Link2</a>
+</figcaption></figure>
+!! end
+
+!! test
+Link with empty target
+!! input
+[[]]
+!! result
+<p>[[]]
+</p>
+!! end
+
 !! test
 Image with empty attribute (php)
 !! options
@@ -9789,7 +10020,37 @@ parsoid=wt2html
 !! end
 
 !! test
-Image with attributes from template (php)
+1. Block image with individual attributes from templates
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|{{echo|137px}}|This is a caption]]
+!! result
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[24,38,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">137px&lt;/span>"}]]}'><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
+!! end
+
+!! test
+2. Block Image with individual attributes from templates
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|{{echo|thumb}}|{{echo|137px}}|This is a caption]]
+!! result
+<figure typeof="mw:Image/Thumb mw:ExpandedAttrs" data-mw='{"attribs":[["thumbnail",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;thumb&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[18,32,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">thumb&lt;/span>"}],["width",{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;137px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[33,47,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">137px&lt;/span>"}]]}'><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="16" width="137"/></a><figcaption>This is a caption</figcaption></figure>
+!! end
+
+!! test
+3. Inline image with individual attributes from templates
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|{{echo|50px}}]]
+!! result
+<p><span typeof="mw:Image mw:ExpandedAttrs" about="#mwt2" data-mw='{"attribs":[["width",{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;echo&amp;quot;,&amp;quot;href&amp;quot;:&amp;quot;./Template:Echo&amp;quot;},&amp;quot;params&amp;quot;:{&amp;quot;1&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;50px&amp;quot;}},&amp;quot;i&amp;quot;:0}}]}\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[18,31,null,null],&amp;quot;pi&amp;quot;:[[{&amp;quot;k&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;spc&amp;quot;:[&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;]}]]}\">50px&lt;/span>"}]]}' data-parsoid='{"optList":[{"ck":"width","ak":"{{echo|50px}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+!! end
+
+!! test
+Image with multiple attributes from the same template (php)
 !! options
 php
 !! input
@@ -9799,14 +10060,16 @@ php
 
 !! end
 
+## Parsoid does not provide editing support for images where templates produce multiple image attributes.
+## To signal this, we add a 'mw:Placeholder' type to such images. This could change in the future.
 !! test
-Image with attributes from template (parsoid)
+Image with multiple attributes from the same template (parsoid)
 !! options
 parsoid
 !! input
 [[File:Foobar.jpg|{{image_attribs}}]]
 !! result
-<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure>
+<figure class="mw-default-size mw-halign-right" typeof="mw:Image mw:Placeholder"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure>
 !! end
 
 !! test
@@ -9836,7 +10099,7 @@ parsoid
 !! result
 <p>123<span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span>456</p>
 123<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure>456
-123<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180"></a></figure>456
+123<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="25" width="220"></a></figure>456
 !! end
 
 !! test
@@ -9860,6 +10123,54 @@ parsoid
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption3 - accepted</figcaption></figure>
 !! end
 
+!! test
+Image with multiple widths -- use last (php)
+!! options
+php
+!! input
+[[File:Foobar.jpg|200px|300px|caption]]
+!! result
+<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a>
+</p>
+!! end
+
+!! test
+Image with multiple widths -- use last (parsoid)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|200px|300px|caption]]
+!! result
+<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="34" width="300"/></a></span></p>
+!! end
+
+!! test
+Image with multiple alignments -- use first (bug 48664) (php)
+!! options
+php
+!! input
+[[File:Foobar.jpg|thumb|left|right|center|caption]]
+
+[[File:Foobar.jpg|middle|text-top|caption]]
+!! result
+<div class="thumb tleft"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>caption</div></div></div>
+<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" style="vertical-align: middle" /></a>
+</p>
+!! end
+
+!! test
+Image with multiple alignments -- use first (bug 48664) (parsoid)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|left|right|center|caption]]
+
+[[File:Foobar.jpg|middle|text-top|caption]]
+!! result
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<p><span class="mw-default-size mw-valign-middle" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"/></a></span></p>
+!! end
+
 !! test
 Image with width attribute at different positions (php)
 !! options
@@ -9880,15 +10191,40 @@ Image with width attribute at different positions (parsoid)
 !! options
 parsoid
 !! input
-[[File:Foobar.jpg|200px|right|Caption]]
-[[File:Foobar.jpg|right|200px|Caption]]
-[[File:Foobar.jpg|right|Caption|200px]]
+[[File:Foobar.jpg|200x200px|right|Caption]]
+[[File:Foobar.jpg|right|200x200px|Caption]]
+[[File:Foobar.jpg|right|Caption|200x200px]]
 !! result
 <figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure>
 <figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure>
 <figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure>
 !! end
 
+# a sad bit of backward-compatibility
+!! test
+Image with size specified with pxpx (bug 13500, 51628) (php)
+!! options
+php
+!! input
+[[File:Foobar.jpg|20pxpx]]
+[[File:Foobar.jpg|200x20pxpx]]
+!! result
+<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" width="20" height="2" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/30px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/40px-Foobar.jpg 2x" /></a>
+<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/177px-Foobar.jpg" width="177" height="20" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/265px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/353px-Foobar.jpg 2x" /></a>
+</p>
+!! end
+
+!! test
+Image with size specified with pxpx (bug 13500, 51628) (parsoid)
+!! options
+parsoid=wt2html,wt2wt
+!! input
+[[File:Foobar.jpg|20pxpx]]
+[[File:Foobar.jpg|200x20pxpx]]
+!! result
+<p><span typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="2" width="20"/></a></span><span typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="20" width="177"/></a></span></p>
+!! end
+
 !! test
 Image with link parameter, wiki target (php)
 !! options
@@ -10360,6 +10696,45 @@ Parsoid: Image caption containing leading space
 
 !!end
 
+!! test
+Image caption containing a table (php)
+!! options
+php
+!! input
+[[Image:Foobar.jpg|thumb|200px|This is an example image thumbnail caption with a table
+{|
+! Foo !! Bar
+|-
+| Foo1 || Bar1
+|}
+and some more text.]]
+!! result
+<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is an example image thumbnail caption with a table <table> <tr> <th> Foo </th> <th> Bar </th></tr> <tr> <td> Foo1 </td> <td> Bar1 </td></tr></table> and some more text.</div></div></div>
+
+!!end
+
+!! test
+Image caption containing a table (parsoid)
+!! options
+parsoid
+!! input
+[[Image:Foobar.jpg|thumb|200px|This is an example image thumbnail caption with a table
+{|
+! Foo !! Bar
+|-
+| Foo1 || Bar1
+|}
+and some more text.]]
+!! result
+<figure typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="23" width="200"/></a><figcaption>This is an example image thumbnail caption with a table
+<table>
+<tbody>
+<tr><th>Foo </th><th>Bar</th></tr>
+<tr>
+<td>Foo1 </td>
+<td>Bar1</td></tr></tbody></table>and some more text.</figcaption></figure>
+!! end
+
 !! test
 Bug 3090: External links other than http: in image captions
 !! input
@@ -10447,10 +10822,9 @@ Parsoid-specific image handling - simple image with size and middle alignment
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|50px|middle]]
+[[File:Foobar.jpg|middle|50px]]
 !! result
-<p>
-<span class="mw-valign-middle" typeof="mw:Image">
+<p><span class="mw-valign-middle" typeof="mw:Image">
 <a href="File:Foobar.jpg">
 <img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50">
 </a>
@@ -10459,30 +10833,41 @@ parsoid
 !! end
 
 !! test
-Parsoid-specific image handling - simple image with both sizes, a baseline alignment, and a caption
+Parsoid-specific image handling - simple image with size, middle alignment,
+non-standard namespace alias
 !! options
-parsoid
+parsoid=wt2wt,wt2html,html2html
 !! input
-[[Image:Foobar.jpg|500x10px|baseline|caption]]
+[[Image:Foobar.jpg|middle|50px]]
 !! result
-<p>
-<span class="mw-valign-baseline" typeof="mw:Image" data-mw="{&quot;caption&quot;:&quot;caption&quot;}">
+<p><span class="mw-valign-middle" typeof="mw:Image">
 <a href="File:Foobar.jpg">
-<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/89px-Foobar.jpg" height="10" width="89">
+<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50">
 </a>
 </span>
 </p>
 !! end
 
 !! test
-Parsoid-specific image handling - simple image with border and size spec
+Parsoid-specific image handling - simple image with size and middle alignment
+(existing content)
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|50px|border|caption]]
+[[File:Foobar.jpg|50px|middle]]
 !! result
-<p>
-<span class="mw-image-border" typeof="mw:Image" data-mw="{&quot;caption&quot;:&quot;caption&quot;}">
+<p><span class="mw-valign-middle" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"50px"},{"ck":"middle","ak":"middle"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+!! end
+
+!! test
+Parsoid-specific image handling - simple image with size and middle alignment
+and non-standard namespace name
+!! options
+parsoid=wt2html,wt2wt,html2html
+!! input
+[[Image:Foobar.jpg|50px|middle]]
+!! result
+<p><span class="mw-valign-middle" typeof="mw:Image">
 <a href="File:Foobar.jpg">
 <img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50">
 </a>
@@ -10490,27 +10875,58 @@ parsoid
 </p>
 !! end
 
+!! test
+Parsoid-specific image handling - simple image with both sizes, a baseline alignment, and a caption
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|500x10px|baseline|caption]]
+!! result
+<p><span class="mw-valign-baseline" typeof="mw:Image" data-mw='{"caption":"caption"}' data-parsoid='{"optList":[{"ck":"width","ak":"500x10px"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption"}],"size":"500x10"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/89px-Foobar.jpg" height="10" width="89" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"10","width":"89"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+!! end
+
+!! test
+Parsoid-specific image handling - simple image with border and size spec
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|50px|border|caption]]
+!! result
+<p><span class="mw-image-border" typeof="mw:Image" data-mw='{"caption":"caption"}' data-parsoid='{"optList":[{"ck":"width","ak":"50px"},{"ck":"border","ak":"border"},{"ck":"caption","ak":"caption"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+!! end
+
 !! test
 Parsoid-specific image handling - thumbnail with halign, valign, and caption
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|thumb|left|baseline|caption content]]
+[[File:Foobar.jpg|left|baseline|thumb|caption content]]
 !! result
 <figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb">
 <a href="File:Foobar.jpg">
-<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="21" width="180" />
+<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="25" width="220" />
 </a>
 <figcaption>caption content</figcaption>
 </figure>
 !! end
 
+!! test
+Parsoid-specific image handling - thumbnail with halign, valign, and caption
+(existing content)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|left|baseline|caption content]]
+!! result
+<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption content</figcaption></figure>
+!! end
+
 !! test
 Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|thumb|50x50px|right|middle|caption]]
+[[Image:Foobar.jpg|right|middle|thumb|50x50px|caption]]
 !! result
 <figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb">
 <a href="File:Foobar.jpg">
@@ -10520,12 +10936,23 @@ parsoid
 </figure>
 !! end
 
+!! test
+Parsoid-specific image handling - thumbnail with specific size, halign,
+valign, and caption (existing content)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|50x50px|right|middle|caption]]
+!! result
+<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"50x50px"},{"ck":"right","ak":"right"},{"ck":"middle","ak":"middle"},{"ck":"caption","ak":"caption"}],"size":"50x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
+!! end
+
 !! test
 Parsoid-specific image handling - framed image with specific size and caption
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|500x50px|frame|caption]]
+[[Image:Foobar.jpg|frame|500x50px|caption]]
 !! result
 <figure typeof="mw:Image/Frame">
 <a href="File:Foobar.jpg">
@@ -10535,12 +10962,23 @@ parsoid
 </figure>
 !! end
 
+!! test
+Parsoid-specific image handling - framed image with specific size and caption
+(existing content)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|442x50px|frame|caption]]
+!! result
+<figure typeof="mw:Image/Frame" data-parsoid='{"optList":[{"ck":"width","ak":"442x50px"},{"ck":"framed","ak":"frame"},{"ck":"caption","ak":"caption"}],"size":"442x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"50","width":"442"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
+!! end
+
 !! test
 Parsoid-specific image handling - framed image with specific size, halign, valign, and caption
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|500x50px|frame|left|baseline|caption]]
+[[Image:Foobar.jpg|left|baseline|frame|500x50px|caption]]
 !! result
 <figure class="mw-halign-left mw-valign-baseline" typeof="mw:Image/Frame">
 <a href="File:Foobar.jpg">
@@ -10550,43 +10988,46 @@ parsoid
 </figure>
 !! end
 
+!! test
+Parsoid-specific image handling - framed image with specific size, halign,
+valign, and caption (existing content)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|442x50px|frame|left|baseline|caption]]
+!! result
+<figure class="mw-halign-left mw-valign-baseline" typeof="mw:Image/Frame" data-parsoid='{"optList":[{"ck":"width","ak":"442x50px"},{"ck":"framed","ak":"frame"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption"}],"size":"442x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"50","width":"442"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
+!! end
+
 !! test
 Parsoid-specific image handling - frameless image with specific size, border, and caption
 !! options
 parsoid
 !! input
-[[Image:Foobar.jpg|frameless|500x50px|border|caption]]
+[[File:Foobar.jpg|frameless|442x50px|border|caption]]
 !! result
-<p>
-<span class="mw-image-border" typeof="mw:Image/Frameless" data-mw="{&quot;caption&quot;:&quot;caption&quot;}">
-<a href="File:Foobar.jpg">
-<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" />
-</a>
-</p>
+<p><span class="mw-image-border" typeof="mw:Image/Frameless" data-mw='{"caption":"caption"}' data-parsoid='{"optList":[{"ck":"frameless","ak":"frameless"},{"ck":"width","ak":"442x50px"},{"ck":"border","ak":"border"},{"ck":"caption","ak":"caption"}],"size":"442x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"50","width":"442"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
 !! end
 
-#!! test
-#Parsoid-specific image handling - simple image with a formatted caption
-#!! options
-#parsoid
-#!! input
-#[[Image:Foobar.jpg|<table><tr><td>a</td><td>b</td></tr><tr><td>c</td></tr></table>]]
-#!! result
-#<p>
-#<span typeof="mw:Image">
-#<a class="mw-default-size" href="Image:Foobar.jpg">
-#<img alt="Foobar.jpg" class="mw-default-size" src="http://example.com/images/3/3a/Foobar.jpg" height="220" width="1941">
-#</a>
-#<span>abc</span>
-#</span>
-#</p>
+!! test
+Parsoid-specific image handling - simple image with a formatted caption
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|<table><tr><td>a</td><td>b</td></tr><tr><td>c</td></tr></table>]]
+!! result
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"&lt;table>&lt;tr>&lt;td>a&lt;/td>&lt;td>b&lt;/td>&lt;/tr>&lt;tr>&lt;td>c&lt;/td>&lt;/tr>&lt;/table>"}'>
+<a href="File:Foobar.jpg">
+<img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941">
+</a></span></p>
+!! end
 
 !! test
 Parsoid-specific image handling - caption with a template in it
 !! options
 parsoid
 !! input
-[[File:Foobar.jpg|thumb|200x200px|This caption has a {{echo|transclusion}} in it.]]
+[[File:Foobar.jpg|thumb|200x23px|This caption has a {{echo|transclusion}} in it.]]
 !! result
 <figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>This caption has a <span about="#mwt1" typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;transclusion&quot;}},&quot;i&quot;:0}}]}">transclusion</span> in it.</figcaption></figure>
 !! end
@@ -10605,6 +11046,40 @@ bar
 <p>bar</p>
 !! end
 
+!! test
+Parsoid-specific image handling - empty caption
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="25" width="220"/></a><figcaption></figcaption></figure>
+!! end
+
+!! test
+Parsoid-specific image handling - whitespace caption
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb| ]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="25" width="220"/></a><figcaption> </figcaption></figure>
+!! end
+
+!! test
+Parsoid-specific image handling - lang option
+!! options
+parsoid
+!! input
+foo
+[[File:Foobar.svg|lang=de|caption]]
+bar
+!! result
+<p>foo
+<span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/f/ff/Foobar.svg" lang="de" height="180" width="240"/></a></span>
+bar</p>
+!! end
+
 
 ###
 ### Subpages
@@ -14442,6 +14917,15 @@ ISBN ISBN 1234567890
 </p>
 !! end
 
+!! test
+ISBN with an X
+!! input
+ISBN 3-462-04561-X
+!! result
+<p><a href="/wiki/Special:BookSources/346204561X" class="internal mw-magiclink-isbn">ISBN 3-462-04561-X</a>
+</p>
+!! end
+
 !! test
 Bug 22905: <abbr> followed by ISBN followed by </a>
 !! input
@@ -17036,10 +17520,10 @@ A <ref>
 
 <references />
 !!result
-<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"This is a &lt;b data-parsoid=&#39;{\"dsr\":[19,40,3,3]}&#39;>&lt;a rel=\"mw:WikiLink\" href=\"./Bolded_link\" data-parsoid=&#39;{\"stx\":\"simple\",\"a\":{\"href\":\"./Bolded_link\"},\"sa\":{\"href\":\"bolded link\"},\"dsr\":[22,37,2,2]}&#39;>bolded link&lt;/a>&lt;/b> and this is a &lt;span about=\"#mwt5\" typeof=\"mw:Transclusion\" data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"transclusion\"}},\"i\":0}}]}&#39; data-parsoid=&#39;{\"dsr\":[55,76,null,null],\"pi\":[[{\"k\":\"1\",\"spc\":[\"\",\"\",\"\",\"\"]}]]}&#39;>transclusion&lt;/span>\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p>
+<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"This is a &lt;b data-parsoid=&#39;{\"dsr\":[19,40,3,3]}&#39;>&lt;a rel=\"mw:WikiLink\" href=\"./Bolded_link\" data-parsoid=&#39;{\"stx\":\"simple\",\"a\":{\"href\":\"./Bolded_link\"},\"sa\":{\"href\":\"bolded link\"},\"dsr\":[22,37,2,2]}&#39;>bolded link&lt;/a>&lt;/b> and this is a &lt;span about=\"#mwt3\" typeof=\"mw:Transclusion\" data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"transclusion\"}},\"i\":0}}]}&#39; data-parsoid=&#39;{\"dsr\":[55,76,null,null],\"pi\":[[{\"k\":\"1\",\"spc\":[\"\",\"\",\"\",\"\"]}]]}&#39;>transclusion&lt;/span>\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p>
 
 <ol class="references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> This is a <b><a rel="mw:WikiLink" href="./Bolded_link">bolded link</a></b> and this is a <span about="#mwt5" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
+<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> This is a <b><a rel="mw:WikiLink" href="./Bolded_link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
 </li>
 </ol>
 !!end
@@ -17142,11 +17626,11 @@ A <ref> <b> foo </ref> B C
 
 <references />
 !!result
-<p data-parsoid='{"dsr":[0,26,0,0]}'>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"&lt;b data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[8,16,3,0]}&#39;> foo &lt;/b>"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref> &lt;b> foo &lt;/ref>","dsr":[2,22,5,6]}'><a href="#cite_note-1">[1]</a></span> B C</p>
+<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"&lt;b data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[8,16,3,0]}&#39;> foo &lt;/b>"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref> &lt;b> foo &lt;/ref>"}'><a href="#cite_note-1">[1]</a></span> B C</p>
 
 
-<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-parsoid='{"src":"&lt;references />","dsr":[28,42,2,2]}' data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> <b data-parsoid='{"stx":"html","autoInsertedEnd":true,"dsr":[8,16,3,0]}'> foo </b></li>
+<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-parsoid='{"src":"&lt;references />"}' data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> <b data-parsoid='{"stx":"html","autoInsertedEnd":true}'> foo </b></li>
 </ol>
 !!end
 
@@ -17158,8 +17642,8 @@ parsoid
 A <ref>foo</ref> B
 C <ref>bar</ref> D
 !!result
-<p data-parsoid='{"dsr":[0,37,0,0]}'>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo&lt;/ref>","dsr":[2,16,5,6]}'><a href="#cite_note-1">[1]</a></span> B
-C <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>bar&lt;/ref>","dsr":[21,35,5,6]}'><a href="#cite_note-2">[2]</a></span> D</p>
+<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo&lt;/ref>"}'><a href="#cite_note-1">[1]</a></span> B
+C <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>bar&lt;/ref>"}'><a href="#cite_note-2">[2]</a></span> D</p>
 !!end
 
 !!test
@@ -17206,9 +17690,9 @@ parsoid
 
 <references />
 !!result
-<p data-parsoid='{"dsr":[0,33,0,0]}'><span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo &amp;lt;ref>bar&amp;lt;/ref> baz"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo &lt;ref>bar&lt;/ref> baz&lt;/ref>","dsr":[0,33,5,6]}'><a href="#cite_note-1">[1]</a></span></p>
+<p><span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo &amp;lt;ref>bar&amp;lt;/ref> baz"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo &lt;ref>bar&lt;/ref> baz&lt;/ref>"}'><a href="#cite_note-1">[1]</a></span></p>
 
-<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-parsoid='{"src":"&lt;references />","dsr":[35,49,2,2]}' data-mw='{"name":"references","attrs":{}}'>
+<ol class="references" typeof="mw:Extension/references" about="#mwt5" data-parsoid='{"src":"&lt;references />"}' data-mw='{"name":"references","attrs":{}}'>
 <li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo &lt;ref>bar&lt;/ref> baz</li>
 </ol>
 !!end
@@ -17267,7 +17751,7 @@ B <ref group="b">bar</ref>
 <references group="a" />
 !!result
 <p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span>
-B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"group":"b"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[b 1]</a></span></p>
+B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"group":"b"}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[b 1]</a></span></p>
 
 <ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li>
 </ol>
@@ -17291,9 +17775,9 @@ B <ref>bar</ref>
 <ol about="#mwt4" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li>
 </ol>
 
-<p>B <span about="#mwt6" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p>
+<p>B <span about="#mwt6" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[1]</a></span></p>
 
-<ol about="#mwt8" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bar</li>
+<ol about="#mwt8" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2-0">↑</a></span> bar</li>
 </ol>
 !!end
 
@@ -17312,14 +17796,14 @@ C <ref>cfoo</ref>
 <references />
 !!result
 <p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"afoo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span>
-B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bfoo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref>bfoo</ref>","dsr":[30,45,5,6]}'><a href="#cite_note-1">[1]</a></span></p>
+B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bfoo"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref>bfoo</ref>"}'><a href="#cite_note-2">[1]</a></span></p>
 
 <ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> afoo</li>
 </ol>
 
-<p>C <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"cfoo"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span></p>
+<p>C <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"cfoo"},"attrs":{}}' id="cite_ref-3-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-3">[2]</a></span></p>
 
-<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bfoo</li><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2-0">↑</a></span> cfoo</li>
+<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2-0">↑</a></span> bfoo</li><li about="#cite_note-3" id="cite_note-3"><span rel="mw:referencedBy"><a href="#cite_ref-3-0">↑</a></span> cfoo</li>
 </ol>
 !!end
 
@@ -17336,11 +17820,11 @@ B <ref name="b">bar</ref>
 This should just get lost.
 </references>
 !!result
-<p data-parsoid='{"dsr":[0,57,0,0]}'>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"a\" />","dsr":[2,18,16,0]}'><a href="#cite_note-a-1">[1]</a></span>
-B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"b\">bar&lt;/ref>","dsr":[21,44,14,6]}'><a href="#cite_note-b-2">[2]</a></span></p>
+<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"a\" />"}'><a href="#cite_note-a-1">[1]</a></span>
+B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"b\">bar&lt;/ref>"}'><a href="#cite_note-b-2">[2]</a></span></p>
 
 
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-parsoid='{"src":"&lt;references>\n&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.\n&lt;/references>","dsr":[46,123,2,2]}' data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.","html":"\n&lt;span about=\"#mwt8\" class=\"reference\" data-mw=&#39;{\"name\":\"ref\",\"body\":{\"html\":\"foo\"},\"attrs\":{\"name\":\"a\"}}&#39; rel=\"dc:references\" typeof=\"mw:Extension/ref\">&lt;a href=\"#cite_note-a-1\">[1]&lt;/a>&lt;/span>\n"},"attrs":{}}'>
+<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-parsoid='{"src":"&lt;references>\n&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.\n&lt;/references>"}' data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"a\">foo&lt;/ref>\nThis should just get lost.","html":"\n&lt;span about=\"#mwt8\" class=\"reference\" data-mw=&#39;{\"name\":\"ref\",\"body\":{\"html\":\"foo\"},\"attrs\":{\"name\":\"a\"}}&#39; rel=\"dc:references\" typeof=\"mw:Extension/ref\">&lt;a href=\"#cite_note-a-1\">[1]&lt;/a>&lt;/span>\n"},"attrs":{}}'>
 <li about="#cite_note-a-1" id="cite_note-a-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-a-1-0">↑</a></span> foo</li>
 <li about="#cite_note-b-2" id="cite_note-b-2" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> bar</li>
 </ol>
@@ -17370,20 +17854,49 @@ B <ref name="b" />
 <ref name="b">foo</ref>
 </references>
 !! result
-<p data-parsoid='{"dsr":[0,45,0,0]}'>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo bar for a"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo bar for a&lt;/ref>","dsr":[2,26,5,6]}'><a href="#cite_note-1">[1]</a></span>
-B <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"b\" />","dsr":[29,45,16,0]}'><a href="#cite_note-b-2">[2]</a></span></p>
+<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo bar for a"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo bar for a&lt;/ref>"}'><a href="#cite_note-1">[1]</a></span>
+B <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"b\" />"}'><a href="#cite_note-b-2">[2]</a></span></p>
 
 
-<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-parsoid='{"src":"&lt;references />","dsr":[47,61,2,2]}' data-mw='{"name":"references","attrs":{}}'>
+<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-parsoid='{"src":"&lt;references />"}' data-mw='{"name":"references","attrs":{}}'>
 <li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo bar for a</li>
 <li about="#cite_note-b-2" id="cite_note-b-2" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> </li></ol>
 
 
-<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-parsoid='{"src":"&lt;references>\n&lt;ref name=\"b\">foo&lt;/ref>\n&lt;/references>","dsr":[63,113,2,2]}' data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"b\">foo&lt;/ref>","html":"\n&lt;span about=\"#mwt10\" class=\"reference\" data-mw=&#39;{\"name\":\"ref\",\"body\":{\"html\":\"foo\"},\"attrs\":{\"name\":\"b\"}}&#39; rel=\"dc:references\" typeof=\"mw:Extension/ref\">&lt;a href=\"#cite_note-b-1\">[1]&lt;/a>&lt;/span>\n"},"attrs":{}}'>
-<li about="#cite_note-b-1" id="cite_note-b-1" data-parsoid="{}"><span rel="mw:referencedBy">↑</span> foo</li>
+<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-parsoid='{"src":"&lt;references>\n&lt;ref name=\"b\">foo&lt;/ref>\n&lt;/references>"}' data-mw='{"name":"references","body":{"extsrc":"&lt;ref name=\"b\">foo&lt;/ref>","html":"\n&lt;span about=\"#mwt10\" class=\"reference\" data-mw=&#39;{\"name\":\"ref\",\"body\":{\"html\":\"foo\"},\"attrs\":{\"name\":\"b\"}}&#39; rel=\"dc:references\" typeof=\"mw:Extension/ref\">&lt;a href=\"#cite_note-b-3\">[1]&lt;/a>&lt;/span>\n"},"attrs":{}}'>
+<li about="#cite_note-b-3" id="cite_note-b-3" data-parsoid="{}"><span rel="mw:referencedBy">↑</span> foo</li>
 </ol>
 !! end
 
+# This test is wt2html only because we're permitting the serializer to produce
+# dirty diffs, normalizing the unclosed references to the self-closed version.
+!! test
+Generate references for unclosed references tag
+!! options
+parsoid=wt2html
+!! input
+a<ref>foo</ref>
+
+<references>
+!! result
+<p data-parsoid='{}'>a<span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref>foo&lt;/ref>"}'><a href="#cite_note-1" data-parsoid="{}">[1]</a></span></p>
+
+
+<ol class="references" typeof="mw:Extension/references" about="#mwt4" data-parsoid='{"src":"&lt;references>"}' data-mw='{"name":"references","attrs":{}}'>
+<li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy" data-parsoid="{}"><a href="#cite_ref-1-0" data-parsoid="{}">↑</a></span> foo</li></ol>
+!! end
+
+!! test
+New reference serializes on its own line
+!! options
+parsoid=wt2wt,html2wt
+!! input
+foo
+<references />
+!! result
+foo<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'></ol>
+!! end
+
 #### ----------------------------------------------------------------
 #### The following section of tests are primarily to test
 #### wikitext escaping capabilities of Parsoid.  Given that
@@ -18111,6 +18624,21 @@ parsoid
 </tbody></table>
 !! end
 
+!! test
+Tables: Digest broken attributes on table and tr tag
+!! options
+parsoid=wt2html
+!! input
+{| || |} ++
+|- || || ++ --
+|}
+!! result
+<table>
+<tbody>
+<tr></tr>
+</tbody></table>
+!! end
+
 #### --------------- Links ----------------
 #### 1. Quote marks in link text
 #### 2. Wikilinks: Escapes needed
@@ -18133,15 +18661,17 @@ Links 2. WikiLinks: Escapes needed
 !! options
 parsoid
 !! input
-[[Foo|<nowiki>[Foobar]</nowiki>]]
+[[Foo|[Foobar]]]
 [[Foo|<nowiki>Foobar]</nowiki>]]
 [[Foo|x [Foobar] x]]
-[[Foo|<nowiki>x [http://google.com g] x</nowiki>]]
+[[Foo|x <nowiki>[http://google.com g]</nowiki> x]]
 [[Foo|<nowiki>[[Bar]]</nowiki>]]
 [[Foo|<nowiki>x [[Bar]] x</nowiki>]]
 [[Foo|<nowiki>|Bar</nowiki>]]
 [[Foo|<nowiki>]]bar</nowiki>]]
 [[Foo|<nowiki>[[bar</nowiki>]]
+[[Foo|<nowiki>x [[ y</nowiki>]]
+[[Foo|<nowiki>x ]] y</nowiki>]]
 [[Foo|<nowiki>x ]] y [[ z</nowiki>]]
 !! result
 <a href="Foo" rel="mw:WikiLink">[Foobar]</a>
@@ -18153,6 +18683,8 @@ parsoid
 <a href="Foo" rel="mw:WikiLink">|Bar</a>
 <a href="Foo" rel="mw:WikiLink">]]bar</a>
 <a href="Foo" rel="mw:WikiLink">[[bar</a>
+<a href="Foo" rel="mw:WikiLink">x [[ y</a>
+<a href="Foo" rel="mw:WikiLink">x ]] y</a>
 <a href="Foo" rel="mw:WikiLink">x ]] y [[ z</a>
 !! end
 
@@ -18829,7 +19361,7 @@ plain text
 !!end
 
 !!test
-Ensure fostered text content is wrapped in spans
+1. Ensure fostered text content is wrapped in spans
 !!options
 parsoid=wt2html
 !!input
@@ -18841,6 +19373,24 @@ parsoid=wt2html
 <table></table>
 !!end
 
+!!test
+2. Ensure fostered text content is wrapped in spans (traps regressions around fostered marker on the span getting lost)
+!!options
+parsoid=wt2html,wt2wt
+!!input
+<table>
+<tr> || ||
+<td> a
+</table>
+!!result
+<span> || ||</span>
+<table>
+<tbody>
+<tr>
+<td> a</td></tr>
+</tbody></table>
+!!end
+
 !!test
 Encapsulation properly handles null DSR information from foster box
 !!options
@@ -19023,14 +19573,24 @@ parsoid=wt2html,wt2wt
 </div>
 |}
 !!result
-<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"OpenTable","href":"./Template:OpenTable"},"params":{},"i":0}},"\n&lt;div>"]}' data-parsoid='{"stx":"html","autoInsertedEnd":true,"dsr":[0,19,null,null],"src":"{{OpenTable}}\n&lt;div>","pi":[[]]}'></div><span about="#mwt1" data-parsoid="{}">
+<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"OpenTable","href":"./Template:OpenTable"},"params":{},"i":0}},"\n&lt;div>"]}' data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[]]}'></div><span about="#mwt1" data-parsoid="{}">
 </span>
-<table about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"dsr":[null,19,2,0]}'></table>
+<table about="#mwt1" data-parsoid='{"autoInsertedEnd":true}'></table>
 
-<table data-parsoid='{"dsr":[20,25,2,2]}'>
+<table>
 </table>
 !!end
 
+!!test
+Support <object> element with .data attribute
+!!options
+parsoid=html2wt
+!!input
+<object data="test.swf"></object>
+!!result
+<object data="test.swf"></object>
+!!end
+
 # -----------------------------------------------------------------
 # The following section of tests are primarily to spec requirements
 # around serialization of new/edited content.
@@ -19039,25 +19599,134 @@ parsoid=wt2html,wt2wt
 # ----------------------------------------------------------------
 
 !! test
-Image: Modifying size of an image
+Image: Modifying size of an image (1)
+!! options
+parsoid=html2wt
+!! input
+[[Image:Foobar.jpg|200x200px]]
+!! result
+<p><span typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"230x230px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/230px-Foobar.jpg" height="22" width="200" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"26","width":"230"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></span></p>
+!!end
+
+!! test
+Image: Modifying size of an image (2)
+!! options
+parsoid=html2wt
+!! input
+[[Image:Foobar.jpg|500x500px]]
+!! result
+<p><span typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"230x230px"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/230px-Foobar.jpg" height="100" width="500" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"26","width":"230"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a></span></p>
+!!end
+
+# note that the data-parsoid value conflicts with the figure's class
+!! test
+Image: Modifying alignment of an image (bug 48665)
+!! options
+parsoid=html2wt
+!! input
+[[Image:Foobar.jpg|thumb|caption|left]]
+!! result
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"caption"},{"ck":"right","ak":"right"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"20","width":"180"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
+!! end
+
+!! test
+Image: Modifying valign of an image (bug 49221)
 !! options
 parsoid=html2wt
 !! input
-[[Image:Wiki.png|230x230px]]
+[[File:Foobar.jpg|20px|text-top]]
 !! result
-<p data-parsoid='{"dsr":[0,24,0,0]}'><span typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100px"}],"cacheKey":"[[Image:Wiki.png|100px]]","img":{"h":115,"w":100,"wdset":true},"dsr":[0,24,null,null]}'><a href="./File:Wiki.png" data-parsoid='{"a":{"href":"./File:Wiki.png"}}'><img resource="./File:Wiki.png" src="//upload.wikimedia.org/wikipedia/en/thumb/b/bc/Wiki.png/100px-Wiki.png" height="230" width="200" data-parsoid='{"a":{"resource":"./File:Wiki.png"},"sa":{"resource":"Image:Wiki.png"}}'></a></span></p>
+<p><span class="mw-valign-text-top" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"20px"},{"ck":"text_top","ak":"text-top"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" height="2" width="20" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"2","width":"20"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></span></p>
+!! end
+
+!! test
+Image: Modifying alt attribute of an image (bug 56400)
+!! options
+parsoid=html2wt
+!! input
+[[File:Foobar.jpg|thumb|some caption|alt=some alternate edited text]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"some caption"},{"ck":"alt","ak":"alt=some alternate text"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img alt="some alternate edited text" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180" data-parsoid='{"a":{"alt":"some alternate edited text","resource":"./File:Foobar.jpg","height":"20","width":"180"},"sa":{"alt":"alt=some alternate edited text","resource":"File:Foobar.jpg"}}'/></a><figcaption>some caption</figcaption></figure>
 !!end
 
 !! test
-Image: New block level image should have \n before and after
+Image: Modifying caption of an image
 !! options
 parsoid=html2wt
 !! input
+[[Image:Foobar.jpg|thumb|new caption]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"original caption"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"20","width":"180"},"sa":{"resource":"Image:Foobar.jpg"}}'/></a><figcaption>new caption</figcaption></figure>
+!!end
+
+!! test
+Image: empty alt attribute (bug 48924)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|alt=|bar]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"alt","ak":"alt="},{"ck":"caption","ak":"bar"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" height="25" width="220" data-parsoid='{"a":{"alt":"","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=","resource":"File:Foobar.jpg"}}'/></a><figcaption>bar</figcaption></figure>
+!! end
+
+#!! test
+#Image: new attributes should be serialized in wiki's language for RTL languages (bug 51852)
+#!! options
+#parsoid=html2wt
+#language=ar
+#!! input
+#[[Imagen:Foobar.jpg|derecha|miniaturadeimagen]]
+#!! result
+#<figure class="mw-default-size mw-halign-right" typeof="mw:Image/Thumb"><a href="Imagen:Foobar.jpg"><img resource="./Imagen:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="20" width="180"/></a></figure>
+#!! end
+
+!! test
+Image: Block level image should have \n before and after
+!! options
+parsoid
+!! input
+123
+[[File:Foobar.jpg|right|thumb|150x150px]]
+456
+!! result
+<p>123</p><figure typeof="mw:Image/Thumb" class="mw-halign-right"><a href="./File:Foobar.png"><img src="http://192.168.142.128/mw/images/thumb/b/bc/Foobar.png/131px-Foobar.png" width="131" height="150" resource="./File:Foobar.png" data-parsoid='{"a":{"resource":"./File:Foobar.png","width":"131"},"sa":{"resource":"File:Foobar.png","width":"150"}}'></a></figure><p>456</p>
+!!end
+
+!! test
+Image: New block level image should have \n before and after (existing
+content)
+!! options
+parsoid
+!! input
 123
-[[File:Wiki.png|right|thumb|150x150px]]
+[[File:Foobar.jpg|right|thumb|150x150px]]
 456
 !! result
-<p>123</p><figure typeof="mw:Image/Thumb" class="mw-halign-right"><a href="./File:Wiki.png"><img src="http://192.168.142.128/mw/images/thumb/b/bc/Wiki.png/131px-Wiki.png" width="131" height="150" resource="./File:Wiki.png"></a></figure><p>456</p>
+<p data-parsoid='{"dsr":[0,3,0,0]}'>123</p>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"right","ak":"right"},{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"150x150px"}],"dsr":[4,45,2,2]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"dsr":[6,43,null,null]}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/150px-Foobar.jpg" height="17" width="150" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"17","width":"150"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure>
+<p data-parsoid='{"dsr":[46,49,0,0]}'>456</p>
+!!end
+
+!! test
+Images: upright option (parsoid)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|thumb|upright|caption]]
+[[File:Foobar.jpg|thumb|upright=0.5|caption]]
+[[File:Foobar.jpg|thumb|500x500px|upright=0.5|caption]]
+!! result
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="19" width="170"/></a><figcaption>caption</figcaption></figure><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="19" width="170"/></a><figcaption>caption</figcaption></figure><figure typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="57" width="500"/></a><figcaption>caption</figcaption></figure>
+!!end
+
+!! test
+Images: upright option is ignored on inline and frame images (parsoid)
+!! options
+parsoid
+!! input
+[[File:Foobar.jpg|500x500px|upright=0.5|caption]]
+!! result
+<p><span typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="57" width="500"/></a></span></p>
 !!end
 
 !! test
@@ -19414,6 +20083,16 @@ parsoid=html2wt
 <a href="//www.ncbi.nlm.nih.gov/pubmed/123?dopt=Abstract" rel="mw:ExtLink">New PMID</a>
 !! end
 
+!! test
+Edited Redirect link should emit a non-piped wikitext link
+!! options
+parsoid=html2wt
+!! input
+#REDIRECT [[Bar]]
+!! result
+<link rel="mw:PageProp/redirect" href="Bar" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./Foo"},"sa":{"href":"Foo"}}'>
+!! end
+
 # -----------------------------------------------------------------
 # End of section for Parsoid-only html2wt tests for serialization
 # of new content
index 87e214c..4d64d05 100644 (file)
@@ -312,7 +312,17 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        // setMwGlobals() on the same global would override the original
                        // value.
                        if ( !array_key_exists( $key, $this->mwGlobals ) ) {
-                               $this->mwGlobals[$key] = $GLOBALS[$key];
+                               // NOTE: we serialize then unserialize the value in case it is an object
+                               // this stops any objects being passed by reference. We could use clone
+                               // and if is_object but this does account for objects within objects!
+                               try{
+                                       $this->mwGlobals[$key] = unserialize( serialize( $GLOBALS[$key] ) );
+                               }
+                               // NOTE; some things such as Closures are not serializable
+                               // in this case just set the value!
+                               catch( Exception $e ) {
+                                       $this->mwGlobals[$key] = $GLOBALS[$key];
+                               }
                        }
 
                        // Override the global
diff --git a/tests/phpunit/ResourceLoaderTestCase.php b/tests/phpunit/ResourceLoaderTestCase.php
new file mode 100644 (file)
index 0000000..b37aa1a
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
+
+       protected static function getResourceLoaderContext() {
+               $resourceLoader = new ResourceLoader();
+               $request = new FauxRequest( array(
+                               'debug' => 'true',
+                               'lang' => 'en',
+                               'modules' => 'startup',
+                               'only' => 'scripts',
+                               'skin' => 'vector',
+                               'target' => 'test',
+               ) );
+               return new ResourceLoaderContext( $resourceLoader, $request );
+       }
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( array(
+                       // For ResourceLoader::inDebugMode since it doesn't have context
+                       'wgResourceLoaderDebug' => true,
+
+                       // Avoid influence from wgInvalidateCacheOnLocalSettingsChange
+                       'wgCacheEpoch' => '20140101000000',
+
+                       // For ResourceLoader::__construct()
+                       'wgResourceLoaderSources' => array(),
+
+                       // For wfScript()
+                       'wgScriptPath' => '/w',
+                       'wgScriptExtension' => '.php',
+                       'wgScript' => '/w/index.php',
+                       'wgLoadScript' => '/w/load.php',
+               ) );
+       }
+}
+
+/* Stubs */
+
+class ResourceLoaderTestModule extends ResourceLoaderModule {}
+
+class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {}
index b09487a..8288cae 100644 (file)
@@ -1,39 +1,31 @@
 <?php
+
 /**
- * Test for the demo xml
+ * Test making sure the demo export xml is valid.
+ * This is NOT a unit test
  *
  * @group Dump
+ * @group large
  */
 class ExportDemoTest extends DumpTestCase {
 
-       /**
-        * @group large
-        */
-       function testExportDemo() {
-               $this->validateXmlFileAgainstXsd( "../../docs/export-demo.xml" );
-       }
-
-       /**
-        * Validates a xml file against the xsd.
-        *
-        * The validation is slow, because php has to read the xsd on each call.
-        *
-        * @param $fname string: name of file to validate
-        */
-       protected function validateXmlFileAgainstXsd( $fname ) {
+       public function testExportDemo() {
+               $fname = "../../docs/export-demo.xml";
                $version = WikiExporter::schemaVersion();
-
                $dom = new DomDocument();
                $dom->load( $fname );
 
                // Ensure, the demo is for the current version
-               $this->assertEquals( $dom->documentElement->getAttribute( 'version' ), $version, 'export-demo.xml should have the current version' );
+               $this->assertEquals(
+                       $dom->documentElement->getAttribute( 'version' ),
+                       $version,
+                       'export-demo.xml should have the current version'
+               );
 
-               try {
-                       $this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ),
-                               "schemaValidate has found an error" );
-               } catch ( Exception $e ) {
-                       $this->fail( "xml not valid against xsd: " . $e->getMessage() );
-               }
+               $this->assertTrue(
+                       $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ),
+                       "schemaValidate has found an error"
+               );
        }
+
 }
index 71ebd6a..7c99352 100644 (file)
@@ -10,6 +10,33 @@ class MessageTest extends MediaWikiLangTestCase {
                ) );
        }
 
+       public function provideTestParams() {
+               return array(
+                       array( array() ),
+                       array( array( 'foo' ), 'foo' ),
+                       array( array( 'foo', 'bar' ), 'foo', 'bar' ),
+                       array( array( 'baz' ), array( 'baz' ) ),
+                       array( array( 'baz', 'foo' ), array( 'baz', 'foo' ) ),
+                       array( array( 'baz', 'foo' ), array( 'baz', 'foo' ), 'hhh' ),
+                       array( array( 'baz', 'foo' ), array( 'baz', 'foo' ), 'hhh', array( 'ahahahahha' ) ),
+                       array( array( 'baz', 'foo' ), array( 'baz', 'foo' ), array( 'ahahahahha' ) ),
+                       array( array( 'baz' ), array( 'baz' ), array( 'ahahahahha' ) ),
+               );
+       }
+
+       /**
+        * @covers Message::params
+        * @dataProvider provideTestParams
+        */
+       public function testParams( $expected ) {
+               $msg = new Message( 'imasomething' );
+
+               $returned = call_user_func_array( array( $msg, 'params' ),  array_slice( func_get_args(), 1 ) );
+
+               $this->assertSame( $msg, $returned );
+               $this->assertEquals( $expected, $msg->getParams() );
+       }
+
        /**
         * @covers Message::exists
         */
@@ -77,55 +104,84 @@ class MessageTest extends MediaWikiLangTestCase {
        }
 
        /**
-        * FIXME: This should not need database, but Language#formatExpiry does (bug 55912)
-        * @group Database
-        * @todo this should be split up into multiple test methods
         * @covers Message::numParams
-        * @covers Message::durationParams
-        * @covers Message::expiryParams
-        * @covers Message::timeperiodParams
-        * @covers Message::sizeParams
-        * @covers Message::bitrateParams
         */
-       public function testMessageParamTypes() {
+       public function testMessageNumParams() {
                $lang = Language::factory( 'en' );
-
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatNum( 123456.789 ),
                        $msg->inLanguage( $lang )->numParams( 123456.789 )->plain(),
                        'numParams is handled correctly'
                );
+       }
 
+       /**
+        * @covers Message::durationParams
+        */
+       public function testMessageDurationParams() {
+               $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatDuration( 1234 ),
                        $msg->inLanguage( $lang )->durationParams( 1234 )->plain(),
                        'durationParams is handled correctly'
                );
+       }
 
+       /**
+        * FIXME: This should not need database, but Language#formatExpiry does (bug 55912)
+        * @group Database
+        * @covers Message::expiryParams
+        */
+       public function testMessageExpiryParams() {
+               $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatExpiry( wfTimestampNow() ),
                        $msg->inLanguage( $lang )->expiryParams( wfTimestampNow() )->plain(),
                        'expiryParams is handled correctly'
                );
+       }
 
+       /**
+        * @covers Message::timeperiodParams
+        */
+       public function testMessageTimeperiodParams() {
+               $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatTimePeriod( 1234 ),
                        $msg->inLanguage( $lang )->timeperiodParams( 1234 )->plain(),
                        'timeperiodParams is handled correctly'
                );
+       }
 
+       /**
+        * @covers Message::sizeParams
+        */
+       public function testMessageSizeParams() {
+               $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatSize( 123456 ),
                        $msg->inLanguage( $lang )->sizeParams( 123456 )->plain(),
                        'sizeParams is handled correctly'
                );
+       }
 
+       /**
+        * @covers Message::bitrateParams
+        */
+       public function testMessageBitrateParams() {
+               $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
+
                $this->assertEquals(
                        $lang->formatBitrate( 123456 ),
                        $msg->inLanguage( $lang )->bitrateParams( 123456 )->plain(),
diff --git a/tests/phpunit/includes/ResourceLoaderModuleTest.php b/tests/phpunit/includes/ResourceLoaderModuleTest.php
deleted file mode 100644 (file)
index 4643319..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-class ResourceLoaderModuleTest extends MediaWikiTestCase {
-
-       protected static function getResourceLoaderContext() {
-               $resourceLoader = new ResourceLoader();
-               $request = new FauxRequest( array(
-                               'debug' => 'false',
-                               'lang' => 'en',
-                               'modules' => 'startup',
-                               'only' => 'scripts',
-                               'skin' => 'vector',
-               ) );
-               return new ResourceLoaderContext( $resourceLoader, $request );
-       }
-
-       /**
-        * @covers ResourceLoaderModule::getDefinitionSummary
-        * @covers ResourceLoaderFileModule::getDefinitionSummary
-        */
-       public function testDefinitionSummary() {
-               $context = self::getResourceLoaderContext();
-
-               $baseParams = array(
-                       'scripts' => array( 'foo.js', 'bar.js' ),
-                       'dependencies' => array( 'jquery', 'mediawiki' ),
-                       'messages' => array( 'hello', 'world' ),
-               );
-
-               $module = new ResourceLoaderFileModule( $baseParams );
-
-               $jsonSummary = json_encode( $module->getDefinitionSummary( $context ) );
-
-               // Exactly the same
-               $module = new ResourceLoaderFileModule( $baseParams );
-
-               $this->assertEquals(
-                       $jsonSummary,
-                       json_encode( $module->getDefinitionSummary( $context ) ),
-                       'Instance is insignificant'
-               );
-
-               // Re-order dependencies
-               $module = new ResourceLoaderFileModule( array(
-                       'dependencies' => array( 'mediawiki', 'jquery' ),
-               ) + $baseParams );
-
-               $this->assertEquals(
-                       $jsonSummary,
-                       json_encode( $module->getDefinitionSummary( $context ) ),
-                       'Order of dependencies is insignificant'
-               );
-
-               // Re-order messages
-               $module = new ResourceLoaderFileModule( array(
-                       'messages' => array( 'world', 'hello' ),
-               ) + $baseParams );
-
-               $this->assertEquals(
-                       $jsonSummary,
-                       json_encode( $module->getDefinitionSummary( $context ) ),
-                       'Order of messages is insignificant'
-               );
-
-               // Re-order scripts
-               $module = new ResourceLoaderFileModule( array(
-                       'scripts' => array( 'bar.js', 'foo.js' ),
-               ) + $baseParams );
-
-               $this->assertNotEquals(
-                       $jsonSummary,
-                       json_encode( $module->getDefinitionSummary( $context ) ),
-                       'Order of scripts is significant'
-               );
-
-               // Subclass
-               $module = new ResourceLoaderFileModuleTestModule( $baseParams );
-
-               $this->assertNotEquals(
-                       $jsonSummary,
-                       json_encode( $module->getDefinitionSummary( $context ) ),
-                       'Class is significant'
-               );
-       }
-}
-
-class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {}
diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php
deleted file mode 100644 (file)
index ca8b2b6..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-
-class ResourceLoaderTest extends MediaWikiTestCase {
-
-       protected static $resourceLoaderRegisterModulesHook;
-
-       protected function setUp() {
-               parent::setUp();
-
-               // $wgResourceLoaderLESSFunctions, $wgResourceLoaderLESSImportPaths; $wgResourceLoaderLESSVars;
-
-               $this->setMwGlobals( array(
-                       'wgResourceLoaderLESSFunctions' => array(
-                               'test-sum' => function ( $frame, $less ) {
-                                       $sum = 0;
-                                       foreach ( $frame[2] as $arg ) {
-                                               $sum += (int)$arg[1];
-                                       }
-                                       return $sum;
-                               },
-                       ),
-                       'wgResourceLoaderLESSImportPaths' => array(
-                               dirname( __DIR__ ) . '/data/less/common',
-                       ),
-                       'wgResourceLoaderLESSVars' => array(
-                               'foo'  => '2px',
-                               'Foo' => '#eeeeee',
-                               'bar' => 5,
-                       ),
-               ) );
-       }
-
-       /* Hook Methods */
-
-       /**
-        * ResourceLoaderRegisterModules hook
-        */
-       public static function resourceLoaderRegisterModules( &$resourceLoader ) {
-               self::$resourceLoaderRegisterModulesHook = true;
-
-               return true;
-       }
-
-       /* Provider Methods */
-       public static function provideValidModules() {
-               return array(
-                       array( 'TEST.validModule1', new ResourceLoaderTestModule() ),
-               );
-       }
-
-       public static function provideResourceLoaderContext() {
-               $resourceLoader = new ResourceLoader();
-               $request = new FauxRequest();
-               return array(
-                       array( new ResourceLoaderContext( $resourceLoader, $request ) ),
-               );
-       }
-
-       /* Test Methods */
-
-       /**
-        * Ensures that the ResourceLoaderRegisterModules hook is called when a new ResourceLoader object is constructed
-        * @covers ResourceLoader::__construct
-        */
-       public function testCreatingNewResourceLoaderCallsRegistrationHook() {
-               self::$resourceLoaderRegisterModulesHook = false;
-               $resourceLoader = new ResourceLoader();
-               $this->assertTrue( self::$resourceLoaderRegisterModulesHook );
-
-               return $resourceLoader;
-       }
-
-       /**
-        * @dataProvider provideValidModules
-        * @depends testCreatingNewResourceLoaderCallsRegistrationHook
-        * @covers ResourceLoader::register
-        * @covers ResourceLoader::getModule
-        */
-       public function testRegisteredValidModulesAreAccessible(
-               $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader
-       ) {
-               $resourceLoader->register( $name, $module );
-               $this->assertEquals( $module, $resourceLoader->getModule( $name ) );
-       }
-
-       /**
-        * @dataProvider provideResourceLoaderContext
-        * @covers ResourceLoaderFileModule::compileLessFile
-        */
-       public function testLessFileCompilation( $context ) {
-               $basePath = __DIR__ . '/../data/less/module';
-               $module = new ResourceLoaderFileModule( array(
-                       'localBasePath' => $basePath,
-                       'styles' => array( 'styles.less' ),
-               ) );
-               $styles = $module->getStyles( $context );
-               $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
-       }
-
-       /**
-        * @dataProvider providePackedModules
-        * @covers ResourceLoader::makePackedModulesString
-        */
-       public function testMakePackedModulesString( $desc, $modules, $packed ) {
-               $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc );
-       }
-
-       /**
-        * @dataProvider providePackedModules
-        * @covers ResourceLoaderContext::expandModuleNames
-        */
-       public function testexpandModuleNames( $desc, $modules, $packed ) {
-               $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
-       }
-
-       public static function providePackedModules() {
-               return array(
-                       array(
-                               'Example from makePackedModulesString doc comment',
-                               array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ),
-                               'foo.bar,baz|bar.baz,quux',
-                       ),
-                       array(
-                               'Example from expandModuleNames doc comment',
-                               array( 'jquery.foo', 'jquery.bar', 'jquery.ui.baz', 'jquery.ui.quux' ),
-                               'jquery.foo,bar|jquery.ui.baz,quux',
-                       ),
-                       array(
-                               'Regression fixed in r88706 with dotless names',
-                               array( 'foo', 'bar', 'baz' ),
-                               'foo,bar,baz',
-                       ),
-                       array(
-                               'Prefixless modules after a prefixed module',
-                               array( 'single.module', 'foobar', 'foobaz' ),
-                               'single.module|foobar,foobaz',
-                       ),
-               );
-       }
-}
-
-/* Stubs */
-
-class ResourceLoaderTestModule extends ResourceLoaderModule {
-}
-
-/* Hooks */
-global $wgHooks;
-$wgHooks['ResourceLoaderRegisterModules'][] = 'ResourceLoaderTest::resourceLoaderRegisterModules';
index f69fad4..e69660e 100644 (file)
@@ -206,10 +206,12 @@ class RevisionStorageTest extends MediaWikiTestCase {
         */
        public function testFetchRevision() {
                $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one', CONTENT_MODEL_WIKITEXT );
-               $id1 = $page->getRevision()->getId();
+
+               // Hidden process cache assertion below
+               $page->getRevision()->getId();
 
                $page->doEditContent( new WikitextContent( 'two' ), 'second rev' );
-               $id2 = $page->getRevision()->getId();
+               $id = $page->getRevision()->getId();
 
                $res = Revision::fetchRevision( $page->getTitle() );
 
@@ -219,9 +221,8 @@ class RevisionStorageTest extends MediaWikiTestCase {
                        $rows[$row->rev_id] = $row;
                }
 
-               $row = $res->fetchObject();
                $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' );
-               $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 );
+               $this->assertArrayHasKey( $id, $rows, 'missing revision with id ' . $id );
        }
 
        /**
index 8516a4c..7e81fab 100644 (file)
@@ -43,12 +43,10 @@ class TestSample extends MediaWikiLangTestCase {
        }
 
        /**
-        * If you want to run a the same test with a variety of data. use a data provider.
+        * If you want to run a the same test with a variety of data, use a data provider.
         * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html
-        *
-        * Note: Data providers are always called statically and outside setUp/tearDown!
         */
-       public static function provideTitles() {
+       public function provideTitles() {
                return array(
                        array( 'Text', NS_MEDIA, 'Media:Text' ),
                        array( 'Text', null, 'Text' ),
index 4386770..209b54c 100644 (file)
@@ -371,20 +371,11 @@ class StatusTest extends MediaWikiLangTestCase {
        /**
         * @dataProvider provideGetMessage
         * @covers Status::getMessage
-        * @todo test with multiple messages at once
+        * @todo test long and short context messages generated through this method
         */
-       public function testGetMessage( Status $status, $expectedParams = array(), $expectedKey, $shortContext = false, $longContext = false ) {
-               $message = $status->getMessage( $shortContext, $longContext );
+       public function testGetMessage( Status $status, $expectedParams = array(), $expectedKey ) {
+               $message = $status->getMessage();
                $this->assertInstanceOf( 'Message', $message );
-
-               // Loop through until we get to the appropriate depth for the message
-               $loops = $shortContext ? 1 : ( $longContext ? 2 : 0 );
-               for( $i = 1; $i <= $loops; $i++ ) {
-                       $params = $message->getParams();
-                       $this->assertInstanceOf( 'Message', $params[0] );
-                       $message = $params[0];
-               }
-
                $this->assertEquals( $expectedParams, $message->getParams() );
                $this->assertEquals( $expectedKey, $message->getKey() );
        }
@@ -392,7 +383,7 @@ class StatusTest extends MediaWikiLangTestCase {
        /**
         * @return array of arrays with values;
         *    0 => status object
-        *    1 => expected Message Params
+        *    1 => expected Message Params (with no context)
         */
        public static function provideGetMessage() {
                $testCases = array();
@@ -411,21 +402,6 @@ class StatusTest extends MediaWikiLangTestCase {
                        'internalerror_info'
                );
 
-               $testCases[ 'GoodButNoErrorShortContext' ] = array(
-                       $status,
-                       array( "Status::getMessage: Invalid result object: no error text but not OK\n" ),
-                       'internalerror_info',
-                       true
-               );
-
-               $testCases[ 'GoodButNoErrorLongContext' ] = array(
-                       $status,
-                       array( "Status::getMessage: Invalid result object: no error text but not OK\n" ),
-                       'internalerror_info',
-                       false,
-                       true
-               );
-
                $status = new Status();
                $status->warning( 'fooBar!' );
                $testCases[ '1StringWarning' ] = array(
@@ -462,33 +438,6 @@ class StatusTest extends MediaWikiLangTestCase {
 //                     "",
 //             );
 
-               $status = new Status();
-               $status->error( new Message( 'fooBar!', array( 'foo', 'bar' )  ) );
-               $testCases[ '1MessageError' ] = array(
-                       $status,
-                       array( 'foo', 'bar' ),
-                       "fooBar!",
-               );
-
-               $status = new Status();
-               $status->error( new Message( 'fooBar!', array( 'foo', 'bar' )  ) );
-               $testCases[ '1MessageErrorShortContext' ] = array(
-                       $status,
-                       array( 'foo', 'bar' ),
-                       "fooBar!",
-                       true,
-               );
-
-               $status = new Status();
-               $status->error( new Message( 'fooBar!', array( 'foo', 'bar' )  ) );
-               $testCases[ '1MessageErrorLongContext' ] = array(
-                       $status,
-                       array( 'foo', 'bar' ),
-                       "fooBar!",
-                       false,
-                       true,
-               );
-
                return $testCases;
        }
 
index 6cf658f..9b41a9c 100644 (file)
@@ -593,8 +593,6 @@ class WikiPageTest extends MediaWikiLangTestCase {
                }
 
                $page = $this->createPage( $title, $text, $model );
-               $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
-                       array( 'pl_from' => $page->getId() ), __METHOD__ );
 
                $editInfo = $page->prepareContentForEdit( $page->getContent() );
 
index 8205029..86b4c35 100644 (file)
@@ -144,10 +144,7 @@ class XmlTest extends MediaWikiTestCase {
                $prevYear = $curYear - 1;
 
                $curMonth = intval( gmdate( 'n' ) );
-               $prevMonth = $curMonth - 1;
-               if ( $prevMonth == 0 ) {
-                       $prevMonth = 12;
-               }
+
                $nextMonth = $curMonth + 1;
                if ( $nextMonth == 13 ) {
                        $nextMonth = 1;
index 0a6607e..ac3f1cd 100644 (file)
@@ -18,6 +18,13 @@ class ApiEditPageTest extends ApiTestCase {
 
                parent::setUp();
 
+               $this->setMwGlobals( array(
+                       'wgExtraNamespaces' => $wgExtraNamespaces,
+                       'wgNamespaceContentModels' => $wgNamespaceContentModels,
+                       'wgContentHandlers' => $wgContentHandlers,
+                       'wgContLang' => $wgContLang,
+               ) );
+
                $wgExtraNamespaces[12312] = 'Dummy';
                $wgExtraNamespaces[12313] = 'Dummy_talk';
 
@@ -31,17 +38,7 @@ class ApiEditPageTest extends ApiTestCase {
        }
 
        protected function tearDown() {
-               global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
-
-               unset( $wgExtraNamespaces[12312] );
-               unset( $wgExtraNamespaces[12313] );
-
-               unset( $wgNamespaceContentModels[12312] );
-               unset( $wgContentHandlers["testing"] );
-
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
-               $wgContLang->resetNamespaces(); # reset namespace cache
-
                parent::tearDown();
        }
 
@@ -215,7 +212,9 @@ class ApiEditPageTest extends ApiTestCase {
                        'text' => "==section 1==\nnew content 1",
                ) );
                $this->assertEquals( 'Success', $re['edit']['result'] );
-               $newtext = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData();
+               $newtext = WikiPage::factory( Title::newFromText( $name ) )
+                       ->getContent( Revision::RAW )
+                       ->getNativeData();
                $this->assertEquals( $newtext, "==section 1==\nnew content 1\n\n==section 2==\ncontent2" );
 
                // Test that we raise a 'nosuchsection' error
@@ -253,7 +252,9 @@ class ApiEditPageTest extends ApiTestCase {
 
                $this->assertEquals( 'Success', $re['edit']['result'] );
                // Check the page text is correct
-               $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData();
+               $text = WikiPage::factory( Title::newFromText( $name ) )
+                       ->getContent( Revision::RAW )
+                       ->getNativeData();
                $this->assertEquals( $text, "== header ==\n\ntest" );
 
                // Now on one that does
@@ -267,7 +268,9 @@ class ApiEditPageTest extends ApiTestCase {
                ));
 
                $this->assertEquals( 'Success', $re2['edit']['result'] );
-               $text = WikiPage::factory( Title::newFromText( $name ) )->getContent( Revision::RAW )->getNativeData();
+               $text = WikiPage::factory( Title::newFromText( $name ) )
+                       ->getContent( Revision::RAW )
+                       ->getNativeData();
                $this->assertEquals( $text, "== header ==\n\ntest\n\n== header ==\n\ntest" );
        }
 
@@ -391,7 +394,6 @@ class ApiEditPageTest extends ApiTestCase {
                $rpage->doEditContent( new WikitextContent( "#REDIRECT [[$name]]" ),
                        "testing 1", EDIT_NEW, false, self::$users['sysop']->user );
                $this->forceRevisionDate( $rpage, '20120101000000' );
-               $baseTime = $rpage->getRevision()->getTimestamp();
 
                // new edit to content
                $page->doEditContent( new WikitextContent( "Foo bar" ),
diff --git a/tests/phpunit/includes/exception/ErrorPageErrorTest.php b/tests/phpunit/includes/exception/ErrorPageErrorTest.php
new file mode 100644 (file)
index 0000000..4cfcd83
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @covers ErrorPageError
+ * @author Adam Shorland
+ */
+class ErrorPageErrorTest extends MediaWikiTestCase {
+
+       private $wgOut;
+
+       protected function setUp() {
+               parent::setUp();
+               global $wgOut;
+               $this->wgOut = clone $wgOut;
+       }
+
+       protected function tearDown() {
+               global $wgOut;
+               $wgOut = $this->wgOut;
+               parent::tearDown();
+       }
+
+       private function getMockMessage() {
+               $mockMessage = $this->getMockBuilder( 'Message' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mockMessage->expects( $this->once() )
+                       ->method( 'inLanguage' )
+                       ->will( $this->returnValue( $mockMessage ) );
+               $mockMessage->expects(  $this->once() )
+                       ->method( 'useDatabase' )
+                       ->will( $this->returnValue( $mockMessage ) );
+               return $mockMessage;
+       }
+
+       public function testConstruction() {
+               $mockMessage = $this->getMockMessage();
+               $title = 'Foo';
+               $params = array( 'Baz' );
+               $e = new ErrorPageError( $title, $mockMessage, $params );
+               $this->assertEquals( $title, $e->title );
+               $this->assertEquals( $mockMessage, $e->msg );
+               $this->assertEquals( $params, $e->params );
+       }
+
+       public function testReport() {
+               $mockMessage = $this->getMockMessage();
+               $title = 'Foo';
+               $params = array( 'Baz' );
+
+               global $wgOut;
+               $wgOut = $this->getMockBuilder( 'OutputPage' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $wgOut->expects( $this->once() )
+                       ->method( 'showErrorPage' )
+                       ->with( $title, $mockMessage, $params );
+               $wgOut->expects( $this->once() )
+                       ->method( 'output' );
+
+               $e = new ErrorPageError( $title, $mockMessage, $params );
+               $e->report();
+       }
+
+
+
+}
diff --git a/tests/phpunit/includes/exception/ReadOnlyErrorTest.php b/tests/phpunit/includes/exception/ReadOnlyErrorTest.php
new file mode 100644 (file)
index 0000000..352ec65
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @covers ReadOnlyError
+ * @author Adam Shorland
+ */
+class ReadOnlyErrorTest extends MediaWikiTestCase {
+
+       public function testConstruction() {
+               $e = new ReadOnlyError();
+               $this->assertEquals( 'readonly', $e->title );
+               $this->assertEquals( 'readonlytext', $e->msg );
+               $this->assertEquals( wfReadOnlyReason()?: array(), $e->params );
+       }
+
+}
diff --git a/tests/phpunit/includes/exception/UserNotLoggedInTest.php b/tests/phpunit/includes/exception/UserNotLoggedInTest.php
new file mode 100644 (file)
index 0000000..591a0fa
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @covers UserNotLoggedIn
+ * @author Adam Shorland
+ */
+class UserNotLoggedInTest extends MediaWikiTestCase {
+
+       public function testConstruction() {
+               $e = new UserNotLoggedIn();
+               $this->assertEquals( 'exception-nologin', $e->title );
+               $this->assertEquals( 'exception-nologin-text', $e->msg );
+               $this->assertEquals( array(), $e->params );
+       }
+
+}
index e24c088..dc5db82 100644 (file)
@@ -32,8 +32,6 @@ class RunningStatTest extends MediaWikiTestCase {
                        return pow( $mean - $x, 2 );
                }, $this->points ) ) / ( count( $rstat ) - 1 );
                $stddev = sqrt( $variance );
-               $min = min( $this->points );
-               $max = max( $this->points );
 
                $this->assertEquals( count( $rstat ), count( $this->points ) );
                $this->assertEquals( $rstat->min, min( $this->points ) );
index aa78394..1670823 100644 (file)
@@ -74,8 +74,6 @@ class BagOStuffTest extends MediaWikiTestCase {
                $fork &= !$this->cache instanceof MultiWriteBagOStuff;
                if ( $fork ) {
                        // callback should take awhile now so that we can test concurrent merge attempts
-                       $usleep = 5000;
-
                        $pid = pcntl_fork();
                        if ( $pid == -1 ) {
                                // can't fork, ignore this test...
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php
new file mode 100644 (file)
index 0000000..b25e9b0
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
+
+       /**
+        * @covers ResourceLoaderModule::getDefinitionSummary
+        * @covers ResourceLoaderFileModule::getDefinitionSummary
+        */
+       public function testDefinitionSummary() {
+               $context = self::getResourceLoaderContext();
+
+               $baseParams = array(
+                       'scripts' => array( 'foo.js', 'bar.js' ),
+                       'dependencies' => array( 'jquery', 'mediawiki' ),
+                       'messages' => array( 'hello', 'world' ),
+               );
+
+               $module = new ResourceLoaderFileModule( $baseParams );
+
+               $jsonSummary = json_encode( $module->getDefinitionSummary( $context ) );
+
+               // Exactly the same
+               $module = new ResourceLoaderFileModule( $baseParams );
+
+               $this->assertEquals(
+                       $jsonSummary,
+                       json_encode( $module->getDefinitionSummary( $context ) ),
+                       'Instance is insignificant'
+               );
+
+               // Re-order dependencies
+               $module = new ResourceLoaderFileModule( array(
+                       'dependencies' => array( 'mediawiki', 'jquery' ),
+               ) + $baseParams );
+
+               $this->assertEquals(
+                       $jsonSummary,
+                       json_encode( $module->getDefinitionSummary( $context ) ),
+                       'Order of dependencies is insignificant'
+               );
+
+               // Re-order messages
+               $module = new ResourceLoaderFileModule( array(
+                       'messages' => array( 'world', 'hello' ),
+               ) + $baseParams );
+
+               $this->assertEquals(
+                       $jsonSummary,
+                       json_encode( $module->getDefinitionSummary( $context ) ),
+                       'Order of messages is insignificant'
+               );
+
+               // Re-order scripts
+               $module = new ResourceLoaderFileModule( array(
+                       'scripts' => array( 'bar.js', 'foo.js' ),
+               ) + $baseParams );
+
+               $this->assertNotEquals(
+                       $jsonSummary,
+                       json_encode( $module->getDefinitionSummary( $context ) ),
+                       'Order of scripts is significant'
+               );
+
+               // Subclass
+               $module = new ResourceLoaderFileModuleTestModule( $baseParams );
+
+               $this->assertNotEquals(
+                       $jsonSummary,
+                       json_encode( $module->getDefinitionSummary( $context ) ),
+                       'Class is significant'
+               );
+       }
+}
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
new file mode 100644 (file)
index 0000000..ab0c8d9
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+
+class ResourceLoaderTest extends ResourceLoaderTestCase {
+
+       protected static $resourceLoaderRegisterModulesHook;
+
+       protected function setUp() {
+               parent::setUp();
+
+               // $wgResourceLoaderLESSFunctions, $wgResourceLoaderLESSImportPaths; $wgResourceLoaderLESSVars;
+
+               $this->setMwGlobals( array(
+                       'wgResourceLoaderLESSFunctions' => array(
+                               'test-sum' => function ( $frame, $less ) {
+                                       $sum = 0;
+                                       foreach ( $frame[2] as $arg ) {
+                                               $sum += (int)$arg[1];
+                                       }
+                                       return $sum;
+                               },
+                       ),
+                       'wgResourceLoaderLESSImportPaths' => array(
+                               dirname( dirname( __DIR__  ) ) . '/data/less/common',
+                       ),
+                       'wgResourceLoaderLESSVars' => array(
+                               'foo'  => '2px',
+                               'Foo' => '#eeeeee',
+                               'bar' => 5,
+                       ),
+               ) );
+       }
+
+       /* Hook Methods */
+
+       /**
+        * ResourceLoaderRegisterModules hook
+        */
+       public static function resourceLoaderRegisterModules( &$resourceLoader ) {
+               self::$resourceLoaderRegisterModulesHook = true;
+
+               return true;
+       }
+
+       /* Provider Methods */
+       public static function provideValidModules() {
+               return array(
+                       array( 'TEST.validModule1', new ResourceLoaderTestModule() ),
+               );
+       }
+
+       /* Test Methods */
+
+       /**
+        * Ensures that the ResourceLoaderRegisterModules hook is called when a new ResourceLoader object is constructed
+        * @covers ResourceLoader::__construct
+        */
+       public function testCreatingNewResourceLoaderCallsRegistrationHook() {
+               self::$resourceLoaderRegisterModulesHook = false;
+               $resourceLoader = new ResourceLoader();
+               $this->assertTrue( self::$resourceLoaderRegisterModulesHook );
+
+               return $resourceLoader;
+       }
+
+       /**
+        * @dataProvider provideValidModules
+        * @depends testCreatingNewResourceLoaderCallsRegistrationHook
+        * @covers ResourceLoader::register
+        * @covers ResourceLoader::getModule
+        */
+       public function testRegisteredValidModulesAreAccessible(
+               $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader
+       ) {
+               $resourceLoader->register( $name, $module );
+               $this->assertEquals( $module, $resourceLoader->getModule( $name ) );
+       }
+
+       /**
+        * @covers ResourceLoaderFileModule::compileLessFile
+        */
+       public function testLessFileCompilation() {
+               $context = self::getResourceLoaderContext();
+               $basePath = __DIR__ . '/../../data/less/module';
+               $module = new ResourceLoaderFileModule( array(
+                       'localBasePath' => $basePath,
+                       'styles' => array( 'styles.less' ),
+               ) );
+               $styles = $module->getStyles( $context );
+               $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
+       }
+
+       /**
+        * @dataProvider providePackedModules
+        * @covers ResourceLoader::makePackedModulesString
+        */
+       public function testMakePackedModulesString( $desc, $modules, $packed ) {
+               $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc );
+       }
+
+       /**
+        * @dataProvider providePackedModules
+        * @covers ResourceLoaderContext::expandModuleNames
+        */
+       public function testexpandModuleNames( $desc, $modules, $packed ) {
+               $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
+       }
+
+       public static function providePackedModules() {
+               return array(
+                       array(
+                               'Example from makePackedModulesString doc comment',
+                               array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ),
+                               'foo.bar,baz|bar.baz,quux',
+                       ),
+                       array(
+                               'Example from expandModuleNames doc comment',
+                               array( 'jquery.foo', 'jquery.bar', 'jquery.ui.baz', 'jquery.ui.quux' ),
+                               'jquery.foo,bar|jquery.ui.baz,quux',
+                       ),
+                       array(
+                               'Regression fixed in r88706 with dotless names',
+                               array( 'foo', 'bar', 'baz' ),
+                               'foo,bar,baz',
+                       ),
+                       array(
+                               'Prefixless modules after a prefixed module',
+                               array( 'single.module', 'foobar', 'foobaz' ),
+                               'single.module|foobar,foobaz',
+                       ),
+               );
+       }
+}
+
+/* Hooks */
+global $wgHooks;
+$wgHooks['ResourceLoaderRegisterModules'][] = 'ResourceLoaderTest::resourceLoaderRegisterModules';
index 397c100..879d821 100644 (file)
@@ -224,9 +224,6 @@ class UploadFromUrlTest extends ApiTestCase {
 
                $this->deleteFile( 'UploadFromUrlTest.png' );
 
-               $talkRev = Revision::newFromTitle( $talk );
-               $talkSize = $talkRev->getSize();
-
                $exception = false;
                try {
                        $this->doApiRequest( array(
@@ -249,6 +246,9 @@ class UploadFromUrlTest extends ApiTestCase {
                return;
                /*
                // Broken until using leavemessage with ignorewarnings is supported
+               $talkRev = Revision::newFromTitle( $talk );
+               $talkSize = $talkRev->getSize();
+
                $job->run();
 
                $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() );
index 1a1bbaf..1eab5a3 100644 (file)
@@ -21,9 +21,6 @@ class UIDGeneratorTest extends MediaWikiTestCase {
                }
 
                $lastId = array_shift( $ids );
-               if ( $hostbits ) {
-                       $lastHost = substr( wfBaseConvert( $lastId, 10, 2, $bits ), -$hostbits );
-               }
 
                $this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
 
diff --git a/tests/phpunit/languages/SpecialPageAliasTest.php b/tests/phpunit/languages/SpecialPageAliasTest.php
new file mode 100644 (file)
index 0000000..8865f68
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * Verifies that special page aliases are valid, with no slashes.
+ *
+ * @group Language
+ * @group SpecialPageAliases
+ * @group SystemTest
+ * @group medium
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+class SpecialPageAliasTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider validSpecialPageAliasesProvider
+        */
+       public function testValidSpecialPageAliases( $code, $specialPageAliases ) {
+               foreach( $specialPageAliases as $specialPage => $aliases ) {
+                       foreach( $aliases as $alias ) {
+                               $msg = "$specialPage alias '$alias' in $code is valid with no slashes";
+                               $this->assertRegExp( '/^[^\/]*$/', $msg );
+                       }
+               }
+       }
+
+       public function validSpecialPageAliasesProvider() {
+               $codes = array_keys( Language::fetchLanguageNames( 'mwfile' ) );
+
+               $data = array();
+
+               foreach( $codes as $code ) {
+                       $specialPageAliases = $this->getSpecialPageAliases( $code );
+
+                       if ( $specialPageAliases !== array() ) {
+                               $data[] = array( $code, $specialPageAliases );
+                       }
+               }
+
+               return $data;
+       }
+
+       /**
+        * @param string $code
+        *
+        * @return array
+        */
+       protected function getSpecialPageAliases( $code ) {
+               $file = Language::getMessagesFileName( $code );
+
+               if ( is_readable( $file ) ) {
+                       include $file;
+
+                       if ( isset( $specialPageAliases ) && $specialPageAliases !== null ) {
+                               return $specialPageAliases;
+                       }
+               }
+
+               return array();
+       }
+
+}
index df00d4d..2393299 100644 (file)
@@ -22,6 +22,7 @@ class StructureTest extends MediaWikiTestCase {
                        'ApiQueryContinueTestBase',
                        'MediaWikiLangTestCase',
                        'MediaWikiTestCase',
+                       'ResourceLoaderTestCase',
                        'PHPUnit_Framework_TestCase',
                        'DumpTestCase',
                ) );
index 63f610f..58509c1 100644 (file)
@@ -8,8 +8,8 @@ return array(
 
        'test.sinonjs' => array(
                'scripts' => array(
-                       'resources/sinonjs/sinon-1.8.1.js',
-                       'resources/sinonjs/sinon-ie-1.8.1.js',
+                       'resources/sinonjs/sinon-1.9.0.js',
+                       'resources/sinonjs/sinon-ie-1.9.0.js',
                ),
                'targets' => array( 'desktop', 'mobile' ),
        ),
@@ -42,8 +42,8 @@ return array(
                        'tests/qunit/suites/resources/jquery/jquery.byteLength.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.client.test.js',
+                       'tests/qunit/suites/resources/jquery/jquery.color.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js',
-                       'tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.hidpi.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js',
@@ -74,6 +74,7 @@ return array(
                        'jquery.byteLength',
                        'jquery.byteLimit',
                        'jquery.client',
+                       'jquery.color',
                        'jquery.colorUtil',
                        'jquery.delayedBind',
                        'jquery.getAttrs',
diff --git a/tests/qunit/suites/resources/jquery/jquery.color.test.js b/tests/qunit/suites/resources/jquery/jquery.color.test.js
new file mode 100644 (file)
index 0000000..b644a3c
--- /dev/null
@@ -0,0 +1,15 @@
+( function ( $ ) {
+       QUnit.module( 'jquery.color', QUnit.newMwEnvironment() );
+
+       QUnit.asyncTest( 'animate', 3, function ( assert ) {
+               var $canvas = $( '<div>' ).css( 'background-color', '#fff' );
+
+               $canvas.animate( { backgroundColor: '#000' }, 4 ).promise().then( function() {
+                       var endColors = $.colorUtil.getRGB( $canvas.css( 'background-color' ) );
+                       assert.strictEqual( endColors[0], 0 );
+                       assert.strictEqual( endColors[1], 0 );
+                       assert.strictEqual( endColors[2], 0 );
+                       QUnit.start();
+               } );
+       } );
+}( jQuery ) );
diff --git a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js b/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js
deleted file mode 100644 (file)
index 234b19c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-( function ( $ ) {
-       QUnit.asyncTest( 'jquery.delayedBind with data option', 2, function ( assert ) {
-               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
-                       data = {
-                               magic: 'beeswax'
-                       },
-                       delay = 50;
-
-               $fixture.delayedBind( delay, 'testevent', data, function ( e ) {
-                       assert.ok( true, 'testevent fired' );
-                       assert.ok( e.data === data, 'data is passed through delayedBind' );
-                       QUnit.start();
-               } );
-
-               // We'll trigger it thrice, but it should only happen once.
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-       } );
-
-       QUnit.asyncTest( 'jquery.delayedBind without data option', 1, function ( assert ) {
-               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
-                       delay = 50;
-
-               $fixture.delayedBind( delay, 'testevent', function () {
-                       assert.ok( true, 'testevent fired' );
-                       QUnit.start();
-               } );
-
-               // We'll trigger it thrice, but it should only happen once.
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-               $fixture.trigger( 'testevent', {} );
-       } );
-}( jQuery ) );
index 3c508d4..bfb857d 100644 (file)
 
        // This test is first because if it fails, then almost all of the latter tests are meaningless.
        QUnit.asyncTest( 'testing hooks/triggers', 4, function ( assert ) {
-               var $collapsible, $content, $toggle;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' + loremIpsum + '</div>'
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
-               $toggle = $collapsible.find( '.mw-collapsible-toggle' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>'
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' ),
+                       $toggle = $collapsible.find( '.mw-collapsible-toggle' );
 
                // In one full collapse-expand cycle, each event will be fired once
 
@@ -34,7 +33,6 @@
                        } );
                        $collapsible.on( 'afterExpand.mw-collapsible', function () {
                                assert.assertTrue( $content.is( ':visible' ), 'second afterCollapseExpand: content is visible' );
-
                                QUnit.start();
                        } );
 
        } );
 
        QUnit.asyncTest( 'basic operation (<div>)', 5, function ( assert ) {
-               var $collapsible, $content, $toggle;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' + loremIpsum + '</div>'
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
-               $toggle = $collapsible.find( '.mw-collapsible-toggle' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>'
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' ),
+                       $toggle = $collapsible.find( '.mw-collapsible-toggle' );
 
                assert.equal( $content.length, 1, 'content is present' );
                assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
        } );
 
        QUnit.asyncTest( 'basic operation (<table>)', 7, function ( assert ) {
-               var $collapsible, $headerRow, $contentRow, $toggle;
-               $collapsible = prepareCollapsible(
-                       '<table class="mw-collapsible">' +
-                               '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
-                               '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
-                               '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
-                       '</table>'
-               );
-               $headerRow = $collapsible.find( 'tr:first' );
-               $contentRow = $collapsible.find( 'tr:last' );
+               var $collapsible = prepareCollapsible(
+                               '<table class="mw-collapsible">' +
+                                       '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
+                                       '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
+                                       '<tr><td>' + loremIpsum + '</td><td>' + loremIpsum + '</td></tr>' +
+                               '</table>'
+                       ),
+                       $headerRow = $collapsible.find( 'tr:first' ),
+                       $contentRow = $collapsible.find( 'tr:last' ),
+                       $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
 
-               $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
                assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' );
 
                assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
        } );
 
        function tableWithCaptionTest( $collapsible, assert ) {
-               var $caption, $headerRow, $contentRow, $toggle;
+               var $caption = $collapsible.find( 'caption' ),
+                       $headerRow = $collapsible.find( 'tr:first' ),
+                       $contentRow = $collapsible.find( 'tr:last' ),
+                       $toggle = $caption.find( '.mw-collapsible-toggle' );
 
-               $caption = $collapsible.find( 'caption' );
-               $headerRow = $collapsible.find( 'tr:first' );
-               $contentRow = $collapsible.find( 'tr:last' );
-
-               $toggle = $caption.find( '.mw-collapsible-toggle' );
                assert.equal( $toggle.length, 1, 'toggle is added to the end of the caption' );
 
                assert.assertTrue( $caption.is( ':visible' ), 'caption is visible' );
        } );
 
        function listTest( listType, assert ) {
-               var $collapsible, $toggleItem, $contentItem, $toggle;
-               $collapsible = prepareCollapsible(
-                       '<' + listType + ' class="mw-collapsible">' +
-                               '<li>' + loremIpsum + '</li>' +
-                               '<li>' + loremIpsum + '</li>' +
-                       '</' + listType + '>'
-               );
-               $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' );
-               $contentItem = $collapsible.find( 'li:last' );
-
-               $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
+               var $collapsible = prepareCollapsible(
+                               '<' + listType + ' class="mw-collapsible">' +
+                                       '<li>' + loremIpsum + '</li>' +
+                                       '<li>' + loremIpsum + '</li>' +
+                               '</' + listType + '>'
+                       ),
+                       $toggleItem = $collapsible.find( 'li.mw-collapsible-toggle-li:first-child' ),
+                       $contentItem = $collapsible.find( 'li:last' ),
+                       $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
+
                assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
 
                assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' );
        } );
 
        QUnit.test( 'basic operation when synchronous (options.instantHide)', 2, function ( assert ) {
-               var $collapsible, $content;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' + loremIpsum + '</div>',
-                       { instantHide: true }
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>',
+                               { instantHide: true }
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' );
 
                assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
 
        } );
 
        QUnit.test( 'mw-made-collapsible data added', 1, function ( assert ) {
-               var $collapsible;
-               $collapsible = prepareCollapsible(
-                       '<div>' + loremIpsum + '</div>'
-               );
+               var $collapsible = prepareCollapsible(
+                               '<div>' + loremIpsum + '</div>'
+                       );
+
                assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
        } );
 
        QUnit.test( 'mw-collapsible added when missing', 1, function ( assert ) {
-               var $collapsible;
-               $collapsible = prepareCollapsible(
-                       '<div>' + loremIpsum + '</div>'
-               );
+               var $collapsible = prepareCollapsible(
+                               '<div>' + loremIpsum + '</div>'
+                       );
+
                assert.assertTrue( $collapsible.hasClass( 'mw-collapsible' ), 'mw-collapsible class present' );
        } );
 
        QUnit.test( 'mw-collapsed added when missing', 1, function ( assert ) {
-               var $collapsible;
-               $collapsible = prepareCollapsible(
+               var $collapsible = prepareCollapsible(
                        '<div>' + loremIpsum + '</div>',
-                       { collapsed: true }
-               );
+                               { collapsed: true }
+                       );
+
                assert.assertTrue( $collapsible.hasClass( 'mw-collapsed' ), 'mw-collapsed class present' );
        } );
 
        QUnit.asyncTest( 'initial collapse (mw-collapsed class)', 2, function ( assert ) {
-               var $collapsible, $content;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>'
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible mw-collapsed">' + loremIpsum + '</div>'
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' );
 
                // Synchronous - mw-collapsed should cause instantHide: true to be used on initial collapsing
                assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
        } );
 
        QUnit.asyncTest( 'initial collapse (options.collapsed)', 2, function ( assert ) {
-               var $collapsible, $content;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' + loremIpsum + '</div>',
-                       { collapsed: true }
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>',
+                               { collapsed: true }
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' );
 
                // Synchronous - collapsed: true should cause instantHide: true to be used on initial collapsing
                assert.assertTrue( $content.is( ':hidden' ), 'content is hidden' );
        } );
 
        QUnit.test( 'clicks on links inside toggler pass through (options.linksPassthru)' , 2, function ( assert ) {
-               var $collapsible, $content;
-
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' +
-                               '<div class="mw-collapsible-toggle">' +
-                                       'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' +
-                               '</div>' +
-                               '<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
-                       '</div>',
-                       // Can't do asynchronous because we're testing that the event *doesn't* happen
-                       { instantHide: true }
-               );
-               $content = $collapsible.find( '.mw-collapsible-content' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' +
+                                       '<div class="mw-collapsible-toggle">' +
+                                               'Toggle <a href="#top">toggle</a> toggle <b>toggle</b>' +
+                                       '</div>' +
+                                       '<div class="mw-collapsible-content">' + loremIpsum + '</div>' +
+                               '</div>',
+                               // Can't do asynchronous because we're testing that the event *doesn't* happen
+                               { instantHide: true }
+                       ),
+                       $content = $collapsible.find( '.mw-collapsible-content' );
 
                $collapsible.find( '.mw-collapsible-toggle a' ).trigger( 'click' );
                assert.assertTrue( $content.is( ':visible' ), 'click event on link inside toggle passes through (content not toggled)' );
        } );
 
        QUnit.asyncTest( 'collapse/expand text (data-collapsetext, data-expandtext)', 2, function ( assert ) {
-               var $collapsible, $toggleLink;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' +
-                               loremIpsum +
-                       '</div>'
-               );
-               $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible" data-collapsetext="Collapse me!" data-expandtext="Expand me!">' +
+                                       loremIpsum +
+                               '</div>'
+                       ),
+                       $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
 
                assert.equal( $toggleLink.text(), 'Collapse me!', 'data-collapsetext is respected' );
 
        } );
 
        QUnit.asyncTest( 'collapse/expand text (options.collapseText, options.expandText)', 2, function ( assert ) {
-               var $collapsible, $toggleLink;
-               $collapsible = prepareCollapsible(
-                       '<div class="mw-collapsible">' + loremIpsum + '</div>',
-                       { collapseText: 'Collapse me!', expandText: 'Expand me!' }
-               );
-               $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
+               var $collapsible = prepareCollapsible(
+                               '<div class="mw-collapsible">' + loremIpsum + '</div>',
+                               { collapseText: 'Collapse me!', expandText: 'Expand me!' }
+                       ),
+                       $toggleLink = $collapsible.find( '.mw-collapsible-toggle a' );
 
                assert.equal( $toggleLink.text(), 'Collapse me!', 'options.collapseText is respected' );
 
index 2bed9b9..70bcaf9 100644 (file)
@@ -1,28 +1,29 @@
-( function ( mw, $ ) {
-       QUnit.module( 'mediawiki.api.parse', QUnit.newMwEnvironment() );
+( function ( mw ) {
+       QUnit.module( 'mediawiki.api.parse', QUnit.newMwEnvironment( {
+               setup: function () {
+                       this.clock = this.sandbox.useFakeTimers();
+                       this.server = this.sandbox.useFakeServer();
+               },
+               teardown: function () {
+                       this.clock.tick( 1 );
+               }
+       } ) );
 
-       QUnit.asyncTest( 'Hello world', function ( assert ) {
-               var api;
-               QUnit.expect( 6 );
+       QUnit.test( 'Hello world', function ( assert ) {
+               QUnit.expect( 1 );
 
-               api = new mw.Api();
+               var api = new mw.Api();
 
-               api.parse( '\'\'\'Hello world\'\'\'' )
-                       .done( function ( html ) {
-                               // Parse into a document fragment instead of comparing HTML, due to
-                               // presence of Tidy influencing whitespace.
-                               // Html also contains "NewPP report" comment.
-                               var $res = $( '<div>' ).html( html ).children(),
-                                       res = $res.get( 0 );
-                               assert.equal( $res.length, 1, 'Response contains 1 element' );
-                               assert.equal( res.nodeName.toLowerCase(), 'p', 'Response is a paragraph' );
-                               assert.equal( $res.children().length, 1, 'Response has 1 child element' );
-                               assert.equal( $res.children().get( 0 ).nodeName.toLowerCase(), 'b', 'Child element is a bold tag' );
-                               // Trim since Tidy may or may not mess with the spacing here
-                               assert.equal( $.trim( $res.text() ), 'Hello world', 'Response contains given text' );
-                               assert.equal( $res.find( 'b' ).text(), 'Hello world', 'Bold tag wraps the entire, same, text' );
+               api.parse( '\'\'\'Hello world\'\'\'' ).done( function ( html ) {
+                       assert.equal( html, '<p><b>Hello world</b></p>' );
+               } );
 
-                               QUnit.start();
-                       } );
+               this.server.respondWith( /action=parse.*&text='''Hello\+world'''/, function ( request ) {
+                       request.respond( 200, { 'Content-Type': 'application/json' },
+                               '{ "parse": { "text": { "*": "<p><b>Hello world</b></p>" } } }'
+                       );
+               } );
+
+               this.server.respond();
        } );
-}( mediaWiki, jQuery ) );
+}( mediaWiki ) );
index c903193..2ad7622 100644 (file)
@@ -7,7 +7,7 @@
                teardown: function () {
                        this.clock.tick( 1 );
                }
-       }) );
+       } ) );
 
        QUnit.test( 'Basic functionality', function ( assert ) {
                QUnit.expect( 2 );