Merge "Expand SessionManager / AuthManager documentation"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 30 Aug 2016 19:11:13 +0000 (19:11 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 30 Aug 2016 19:11:13 +0000 (19:11 +0000)
144 files changed:
RELEASE-NOTES-1.28
autoload.php
docs/hooks.txt
includes/DefaultSettings.php
includes/EditPage.php
includes/Linker.php
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/Message.php
includes/OutputPage.php
includes/Preferences.php
includes/WebRequest.php
includes/actions/RollbackAction.php
includes/actions/ViewAction.php
includes/api/ApiAuthManagerHelper.php
includes/api/ApiBase.php
includes/api/ApiCSPReport.php
includes/api/ApiErrorFormatter.php
includes/api/ApiPageSet.php
includes/api/ApiParamInfo.php
includes/api/ApiQueryBlocks.php
includes/api/ApiResult.php
includes/api/ApiUpload.php
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/ja.json
includes/api/i18n/mr.json
includes/api/i18n/oc.json
includes/auth/TemporaryPasswordPrimaryAuthenticationProvider.php
includes/db/Database.php
includes/db/DatabaseError.php
includes/db/IDatabase.php
includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LBFactoryMulti.php
includes/db/loadbalancer/LBFactorySimple.php
includes/debug/MWDebug.php
includes/debug/logger/MonologSpi.php
includes/deferred/LinksUpdate.php
includes/htmlform/HTMLFormField.php
includes/installer/Installer.php
includes/installer/LocalSettingsGenerator.php
includes/installer/MysqlUpdater.php
includes/installer/i18n/diq.json
includes/libs/virtualrest/RestbaseVirtualRESTService.php
includes/objectcache/MemcachedPeclBagOStuff.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/Parser.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderSiteStylesModule.php
includes/session/SessionBackend.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPreferences.php
includes/specials/pagers/UsersPager.php
includes/upload/UploadBase.php
languages/Language.php
languages/i18n/aeb-arab.json
languages/i18n/ar.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fr.json
languages/i18n/ga.json
languages/i18n/gl.json
languages/i18n/gu.json
languages/i18n/he.json
languages/i18n/hu.json
languages/i18n/ilo.json
languages/i18n/it.json
languages/i18n/jv.json
languages/i18n/kiu.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/mai.json
languages/i18n/mk.json
languages/i18n/mr.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sl.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/ur.json
languages/i18n/zh-hans.json
maintenance/archives/patch-pl-tl-il-nonunique.sql [new file with mode: 0644]
maintenance/archives/patch-pl-tl-il-unique.sql [deleted file]
maintenance/archives/patch-revision-page-rev-index-nonunique.sql [new file with mode: 0644]
maintenance/sqlite.php
maintenance/tables.sql
maintenance/updateCollation.php
resources/Resources.php
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.special/mediawiki.special.movePage.css
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
resources/src/mediawiki/api.js
resources/src/mediawiki/api/messages.js
resources/src/mediawiki/api/options.js
resources/src/mediawiki/htmlform/hide-if.js
resources/src/mediawiki/htmlform/ooui.styles.css
resources/src/mediawiki/mediawiki.debug.init.js [deleted file]
resources/src/mediawiki/mediawiki.debug.js
resources/src/mediawiki/mediawiki.inspect.js
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.toc.js
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiErrorFormatterTest.php
tests/phpunit/includes/api/ApiPageSetTest.php
tests/phpunit/includes/api/MockApi.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/db/DatabaseTestHelper.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/resourceloader/DerivativeResourceLoaderContextTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php [new file with mode: 0644]
tests/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.options.test.js

index 92ac869..6639a95 100644 (file)
@@ -24,8 +24,11 @@ production.
   input methods provided by the UniversalLanguageSelector extension.
 * When $wgPingback is true, MediaWiki will periodically ping
   https://www.mediawiki.org/beacon with basic information about the local
-  MediaWiki installation.  This data includes, for example, the type of system,
+  MediaWiki installation. This data includes, for example, the type of system,
   PHP version, and chosen database backend. This behavior is off by default.
+* When $EditSubmitButtonLabelPublish is true, MediaWiki will label the button
+  to store-to-database-and-show-to-others as "Publish page"/"Publish changes";
+  if false, the default, they will be "Save page"/"Save changes".
 
 === New features in 1.28 ===
 * User::isBot() method for checking if an account is a bot role account.
@@ -42,6 +45,11 @@ production.
   to 'uca-default-u-kn' or 'uca-<langcode>-u-kn'. If you can't use UCA collations,
   a 'numeric' collation is also available. If migrating from another
   collation, you will need to run the updateCollation.php maintenance script.
+* Two new codes have been added to #time parser function: "xit" for days in current
+  month, and "xiz" for days passed in the year, both in Iranian calendar.
+* mw.Api has a new option, useUS, to use U+001F (Unit Separator) when
+  appropriate for sending multi-valued parameters. This defaults to true when
+  the mw.Api instance seems to be for the local wiki.
 
 === External library changes in 1.28 ===
 
@@ -79,6 +87,15 @@ production.
   action=createaccount, action=linkaccount, and action=changeauthenticationdata
   in the query string is now deprecated and outputs a warning. They should be
   submitted in the POST body instead.
+* (T141960) Multi-valued parameters may now be separated using U+001F (Unit Separator)
+  instead of the pipe character. This will be useful if some of the multiple
+  values need to contain pipes, e.g. for action=options.
+* The API will now warn if input is not NFC-normalized Unicode or if it
+  contains invalid characters.
+* The 'normalized' list output by action=query and other modules that use
+  ApiPageSet may contain entries where the 'from' value is percent-encoded as
+  the raw value cannot be represented in a valid API response. These are
+  indicated by a 'fromencoded' boolean alongside the existing 'from' parameter.
 
 === Action API internal changes in 1.28 ===
 * Added a new hook, 'ApiMakeParserOptions', to allow extensions to better
@@ -100,7 +117,7 @@ changes to languages because of Phabricator reports.
 
 === Other changes in 1.28 ===
 * (T128697) Improved handling of large diffs.
-* [BREAKING CHANGE] $wgExtendedLoginCookies has been removed.  You can
+* [BREAKING CHANGE] $wgExtendedLoginCookies has been removed. You can
   use or update a custom session provider if needed.
 * Deprecated APIEditBeforeSave hook in favor of EditFilterMergedContent.
 * The 'UploadVerification' hook is deprecated. Use 'UploadVerifyFile' instead.
index 39102fd..dec7219 100644 (file)
@@ -297,7 +297,7 @@ $wgAutoloadLocalClasses = [
        'CsvStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'CurlHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
        'DBAccessBase' => __DIR__ . '/includes/dao/DBAccessBase.php',
-       'DBAccessError' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
+       'DBAccessError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBAccessObjectUtils' => __DIR__ . '/includes/dao/DBAccessObjectUtils.php',
        'DBConnRef' => __DIR__ . '/includes/db/DBConnRef.php',
        'DBConnectionError' => __DIR__ . '/includes/db/DatabaseError.php',
@@ -308,7 +308,7 @@ $wgAutoloadLocalClasses = [
        'DBMasterPos' => __DIR__ . '/includes/db/DatabaseUtility.php',
        'DBQueryError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBReadOnlyError' => __DIR__ . '/includes/db/DatabaseError.php',
-       'DBReplicationWaitError' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
+       'DBReplicationWaitError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBSiteStore' => __DIR__ . '/includes/site/DBSiteStore.php',
        'DBTransactionError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBUnexpectedError' => __DIR__ . '/includes/db/DatabaseError.php',
index a0ee8bd..a7fb873 100644 (file)
@@ -596,7 +596,7 @@ $outputPage: OutputPage that can be used to append the output.
 &$user: the user that deleted the article
 $reason: the reason the article was deleted
 $id: id of the article that was deleted
-$content: the Content of the deleted page
+$content: the Content of the deleted page (or null, when deleting a broken page)
 $logEntry: the ManualLogEntry used to record the deletion
 $archivedRevisionCount: the number of revisions archived during the deletion
 
@@ -1937,8 +1937,8 @@ LinkRenderer, before processing starts.  Return false to skip default
 processing and return $ret.
 $linkRenderer: the LinkRenderer object
 $target: the LinkTarget that the link is pointing to
-&$html: the contents that the <a> tag should have (raw HTML); null means
-  "default".
+&$text: the contents that the <a> tag should have; either a plain, unescaped
+  string or a HtmlArmor object; null means "default".
 &$customAttribs: the HTML attributes that the <a> tag should have, in
   associative array form, with keys and values unescaped.  Should be merged
   with default values, with a value of false meaning to suppress the
@@ -1955,7 +1955,8 @@ return false, $ret will be returned.
 $linkRenderer: the LinkRenderer object
 $target: the LinkTarget object that the link is pointing to
 $isKnown: boolean indicating whether the page is known or not
-&$html: the final (raw HTML) contents of the <a> tag, after processing.
+&$text: the contents that the <a> tag should have; either a plain, unescaped
+  string or a HtmlArmor object.
 &$attribs: the final HTML attributes of the <a> tag, after processing, in
   associative array form.
 &$ret: the value to return if your hook returns false.
@@ -3649,6 +3650,16 @@ $userId: User id of the current user
 $userText: User name of the current user
 &$items: Array of user tool links as HTML fragments
 
+'UsersPagerDoBatchLookups': Called in UsersPager::doBatchLookups() to give
+extensions providing user group data from an alternate source a chance to add
+their data into the cache array so that things like global user groups are
+displayed correctly in Special:ListUsers.
+$dbr: Read-only database handle
+$userIds: Array of user IDs whose groups we should look up
+&$cache: Array of user ID -> internal user group name (e.g. 'sysop') mappings
+&$groups: Array of group name -> bool true mappings for members of a given user
+group
+
 'ValidateExtendedMetadataCache': Called to validate the cached metadata in
 FormatMetadata::getExtendedMeta (return false means cache will be
 invalidated and GetExtendedMetadata hook called again).
@@ -3721,7 +3732,8 @@ a page is deleted. Called in WikiPage::getDeletionUpdates(). Note that updates
 specific to a content model should be provided by the respective Content's
 getDeletionUpdates() method.
 $page: the WikiPage
-$content: the Content to generate updates for
+$content: the Content to generate updates for (or null, if the Content could not be loaded
+due to an error)
 &$updates: the array of DataUpdate objects. Hook function may want to add to it.
 
 'XmlDumpWriterOpenPage': Called at the end of XmlDumpWriter::openPage, to allow
index f1afc4c..fa6df8d 100644 (file)
@@ -3200,7 +3200,7 @@ $wgUseMediaWikiUIEverywhere = false;
  *
  * @since 1.28
  */
-$wgEditButtonPublishNotSave = false;
+$wgEditSubmitButtonLabelPublish = false;
 
 /**
  * Permit other namespaces in addition to the w3.org default.
@@ -3756,10 +3756,8 @@ $wgResourceLoaderLESSImportPaths = [
 /**
  * Whether ResourceLoader should attempt to persist modules in localStorage on
  * browsers that support the Web Storage API.
- *
- * @since 1.23 - Client-side module persistence is experimental. Exercise care.
  */
-$wgResourceLoaderStorageEnabled = false;
+$wgResourceLoaderStorageEnabled = true;
 
 /**
  * Cache version for client-side ResourceLoader module storage. You can trigger
@@ -8381,6 +8379,28 @@ $wgEventRelayerConfig = [
  */
 $wgPingback = false;
 
+/**
+ * List of urls which appear often to be triggering CSP reports
+ * but do not appear to be caused by actual content, but by client
+ * software inserting scripts (i.e. Ad-Ware).
+ * List based on results from Wikimedia logs.
+ *
+ * @since 1.28
+ */
+$wgCSPFalsePositiveUrls = [
+       'https://3hub.co' => true,
+       'https://morepro.info' => true,
+       'https://p.ato.mx' => true,
+       'https://s.ato.mx' => true,
+       'https://adserver.adtech.de' => true,
+       'https://ums.adtechus.com' => true,
+       'https://cas.criteo.com' => true,
+       'https://cat.nl.eu.criteo.com' => true,
+       'https://atpixel.alephd.com' => true,
+       'https://rtb.metrigo.com' => true,
+       'https://d5p.de17a.com' => true,
+];
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 738eaec..e0080fa 100644 (file)
@@ -507,6 +507,7 @@ class EditPage {
         * the newly-edited page.
         */
        function edit() {
+               global $wgOut, $wgRequest, $wgUser;
                // Allow extensions to modify/prevent this form or submission
                if ( !Hooks::run( 'AlternateEdit', [ $this ] ) ) {
                        return;
@@ -514,15 +515,13 @@ class EditPage {
 
                wfDebug( __METHOD__ . ": enter\n" );
 
-               $request = $this->context->getRequest();
-               $out = $this->context->getOutput();
                // If they used redlink=1 and the page exists, redirect to the main article
-               if ( $request->getBool( 'redlink' ) && $this->mTitle->exists() ) {
-                       $out->redirect( $this->mTitle->getFullURL() );
+               if ( $wgRequest->getBool( 'redlink' ) && $this->mTitle->exists() ) {
+                       $wgOut->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
-               $this->importFormData( $request );
+               $this->importFormData( $wgRequest );
                $this->firsttime = false;
 
                if ( wfReadOnly() && $this->save ) {
@@ -551,7 +550,7 @@ class EditPage {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $user = $this->context->getUser();
+                               $user = $wgUser;
                                DeferredUpdates::addCallableUpdate( function () use ( $user ) {
                                        $user->spreadAnyEditBlock();
                                } );
@@ -625,14 +624,15 @@ class EditPage {
         * @return array
         */
        protected function getEditPermissionErrors( $rigor = 'secure' ) {
-               $user = $this->context->getUser();
-               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $user, $rigor );
+               global $wgUser;
+
+               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser, $rigor );
                # Can this title be created?
                if ( !$this->mTitle->exists() ) {
                        $permErrors = array_merge(
                                $permErrors,
                                wfArrayDiff2(
-                                       $this->mTitle->getUserPermissionsErrors( 'create', $user, $rigor ),
+                                       $this->mTitle->getUserPermissionsErrors( 'create', $wgUser, $rigor ),
                                        $permErrors
                                )
                        );
@@ -665,12 +665,13 @@ class EditPage {
         * @throws PermissionsError
         */
        protected function displayPermissionsError( array $permErrors ) {
-               $out = $this->context->getOutput();
-               if ( $this->context->getRequest()->getBool( 'redlink' ) ) {
+               global $wgRequest, $wgOut;
+
+               if ( $wgRequest->getBool( 'redlink' ) ) {
                        // The edit page was reached via a red link.
                        // Redirect to the article page and let them click the edit tab if
                        // they really want a permission error.
-                       $out->redirect( $this->mTitle->getFullURL() );
+                       $wgOut->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
@@ -685,7 +686,7 @@ class EditPage {
 
                $this->displayViewSourcePage(
                        $content,
-                       $out->formatPermissionsErrorMessage( $permErrors, 'edit' )
+                       $wgOut->formatPermissionsErrorMessage( $permErrors, 'edit' )
                );
        }
 
@@ -695,28 +696,29 @@ class EditPage {
         * @param string $errorMessage additional wikitext error message to display
         */
        protected function displayViewSourcePage( Content $content, $errorMessage = '' ) {
-               $out = $this->context->getOutput();
-               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$out ] );
+               global $wgOut;
 
-               $out->setRobotPolicy( 'noindex,nofollow' );
-               $out->setPageTitle( wfMessage(
+               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$wgOut ] );
+
+               $wgOut->setRobotPolicy( 'noindex,nofollow' );
+               $wgOut->setPageTitle( wfMessage(
                        'viewsource-title',
                        $this->getContextTitle()->getPrefixedText()
                ) );
-               $out->addBacklinkSubtitle( $this->getContextTitle() );
-               $out->addHTML( $this->editFormPageTop );
-               $out->addHTML( $this->editFormTextTop );
+               $wgOut->addBacklinkSubtitle( $this->getContextTitle() );
+               $wgOut->addHTML( $this->editFormPageTop );
+               $wgOut->addHTML( $this->editFormTextTop );
 
                if ( $errorMessage !== '' ) {
-                       $out->addWikiText( $errorMessage );
-                       $out->addHTML( "<hr />\n" );
+                       $wgOut->addWikiText( $errorMessage );
+                       $wgOut->addHTML( "<hr />\n" );
                }
 
                # If the user made changes, preserve them when showing the markup
                # (This happens when a user is blocked during edit, for instance)
                if ( !$this->firsttime ) {
                        $text = $this->textbox1;
-                       $out->addWikiMsg( 'viewyourtext' );
+                       $wgOut->addWikiMsg( 'viewyourtext' );
                } else {
                        try {
                                $text = $this->toEditText( $content );
@@ -725,21 +727,21 @@ class EditPage {
                                # (e.g. for an old revision with a different model)
                                $text = $content->serialize();
                        }
-                       $out->addWikiMsg( 'viewsourcetext' );
+                       $wgOut->addWikiMsg( 'viewsourcetext' );
                }
 
-               $out->addHTML( $this->editFormTextBeforeContent );
+               $wgOut->addHTML( $this->editFormTextBeforeContent );
                $this->showTextbox( $text, 'wpTextbox1', [ 'readonly' ] );
-               $out->addHTML( $this->editFormTextAfterContent );
+               $wgOut->addHTML( $this->editFormTextAfterContent );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
                        Linker::formatTemplates( $this->getTemplates() ) ) );
 
-               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
-               $out->addHTML( $this->editFormTextBottom );
+               $wgOut->addHTML( $this->editFormTextBottom );
                if ( $this->mTitle->exists() ) {
-                       $out->returnToMain( null, $this->mTitle );
+                       $wgOut->returnToMain( null, $this->mTitle );
                }
        }
 
@@ -749,19 +751,18 @@ class EditPage {
         * @return bool
         */
        protected function previewOnOpen() {
-               global $wgPreviewOnOpenNamespaces;
-               $request = $this->context->getRequest();
-               if ( $request->getVal( 'preview' ) == 'yes' ) {
+               global $wgRequest, $wgUser, $wgPreviewOnOpenNamespaces;
+               if ( $wgRequest->getVal( 'preview' ) == 'yes' ) {
                        // Explicit override from request
                        return true;
-               } elseif ( $request->getVal( 'preview' ) == 'no' ) {
+               } elseif ( $wgRequest->getVal( 'preview' ) == 'no' ) {
                        // Explicit override from request
                        return false;
                } elseif ( $this->section == 'new' ) {
                        // Nothing *to* preview for new sections
                        return false;
-               } elseif ( ( $request->getVal( 'preload' ) !== null || $this->mTitle->exists() )
-                       && $this->context->getUser()->getOption( 'previewonfirst' )
+               } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() )
+                       && $wgUser->getOption( 'previewonfirst' )
                ) {
                        // Standard preference behavior
                        return true;
@@ -814,7 +815,7 @@ class EditPage {
         * @throws ErrorPageError
         */
        function importFormData( &$request ) {
-               global $wgContLang;
+               global $wgContLang, $wgUser;
 
                # Section edit can come from either the form or a link
                $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
@@ -926,14 +927,13 @@ class EditPage {
                        $this->watchthis = $request->getCheck( 'wpWatchthis' );
 
                        # Don't force edit summaries when a user is editing their own user or talk page
-                       $user = $this->context->getUser();
                        if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK )
-                               && $this->mTitle->getText() == $user->getName()
+                               && $this->mTitle->getText() == $wgUser->getName()
                        ) {
                                $this->allowBlankSummary = true;
                        } else {
                                $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' )
-                                       || !$user->getOption( 'forceeditsummary' );
+                                       || !$wgUser->getOption( 'forceeditsummary' );
                        }
 
                        $this->autoSumm = $request->getText( 'wpAutoSummary' );
@@ -1039,6 +1039,7 @@ class EditPage {
         * @return bool If the requested section is valid
         */
        function initialiseForm() {
+               global $wgUser;
                $this->edittime = $this->page->getTimestamp();
                $this->editRevId = $this->page->getLatest();
 
@@ -1047,21 +1048,20 @@ class EditPage {
                        return false;
                }
                $this->textbox1 = $this->toEditText( $content );
-               $user = $this->context->getUser();
 
                // activate checkboxes if user wants them to be always active
                # Sort out the "watch" checkbox
-               if ( $user->getOption( 'watchdefault' ) ) {
+               if ( $wgUser->getOption( 'watchdefault' ) ) {
                        # Watch all edits
                        $this->watchthis = true;
-               } elseif ( $user->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
+               } elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
                        # Watch creations
                        $this->watchthis = true;
-               } elseif ( $user->isWatched( $this->mTitle ) ) {
+               } elseif ( $wgUser->isWatched( $this->mTitle ) ) {
                        # Already watched
                        $this->watchthis = true;
                }
-               if ( $user->getOption( 'minordefault' ) && !$this->isNew ) {
+               if ( $wgUser->getOption( 'minordefault' ) && !$this->isNew ) {
                        $this->minoredit = true;
                }
                if ( $this->textbox1 === false ) {
@@ -1078,11 +1078,9 @@ class EditPage {
         * @since 1.21
         */
        protected function getContentObject( $def_content = null ) {
-               global $wgContLang;
+               global $wgOut, $wgRequest, $wgUser, $wgContLang;
 
                $content = false;
-               $request = $this->context->getRequest();
-               $user = $this->context->getUser();
 
                // For message page not locally set, use the i18n message.
                // For other non-existent articles, use preload text if any.
@@ -1095,10 +1093,10 @@ class EditPage {
                        }
                        if ( $content === false ) {
                                # If requested, preload some text.
-                               $preload = $request->getVal( 'preload',
+                               $preload = $wgRequest->getVal( 'preload',
                                        // Custom preload text for new sections
                                        $this->section === 'new' ? 'MediaWiki:addsection-preload' : '' );
-                               $params = $request->getArray( 'preloadparams', [] );
+                               $params = $wgRequest->getArray( 'preloadparams', [] );
 
                                $content = $this->getPreloadedContent( $preload, $params );
                        }
@@ -1106,15 +1104,15 @@ class EditPage {
                } else {
                        if ( $this->section != '' ) {
                                // Get section edit text (returns $def_text for invalid sections)
-                               $orig = $this->getOriginalContent( $user );
+                               $orig = $this->getOriginalContent( $wgUser );
                                $content = $orig ? $orig->getSection( $this->section ) : null;
 
                                if ( !$content ) {
                                        $content = $def_content;
                                }
                        } else {
-                               $undoafter = $request->getInt( 'undoafter' );
-                               $undo = $request->getInt( 'undo' );
+                               $undoafter = $wgRequest->getInt( 'undoafter' );
+                               $undo = $wgRequest->getInt( 'undo' );
 
                                if ( $undo > 0 && $undoafter > 0 ) {
                                        $undorev = Revision::newFromId( $undo );
@@ -1134,8 +1132,8 @@ class EditPage {
                                                        $undoMsg = 'failure';
                                                } else {
                                                        $oldContent = $this->page->getContent( Revision::RAW );
-                                                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
-                                                       $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
+                                                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+                                                       $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
 
                                                        if ( $newContent->equals( $oldContent ) ) {
                                                                # Tell the user that the undo results in no change,
@@ -1182,13 +1180,12 @@ class EditPage {
 
                                        // Messages: undo-success, undo-failure, undo-norev, undo-nochange
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
-                                       $this->editFormPageTop .= $this->context->getOutput()->parse(
-                                               "<div class=\"{$class}\">" .
+                                       $this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
                                                wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
                                }
 
                                if ( $content === false ) {
-                                       $content = $this->getOriginalContent( $user );
+                                       $content = $this->getOriginalContent( $wgUser );
                                }
                        }
                }
@@ -1385,10 +1382,10 @@ class EditPage {
         * @private
         */
        function tokenOk( &$request ) {
+               global $wgUser;
                $token = $request->getVal( 'wpEditToken' );
-               $user = $this->context->getUser();
-               $this->mTokenOk = $user->matchEditToken( $token );
-               $this->mTokenOkExceptSuffix = $user->matchEditTokenNoSuffix( $token );
+               $this->mTokenOk = $wgUser->matchEditToken( $token );
+               $this->mTokenOkExceptSuffix = $wgUser->matchEditTokenNoSuffix( $token );
                return $this->mTokenOk;
        }
 
@@ -1419,7 +1416,7 @@ class EditPage {
                        $val = 'restored';
                }
 
-               $response = $this->context->getRequest()->response();
+               $response = RequestContext::getMain()->getRequest()->response();
                $response->setCookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION, [
                        'httpOnly' => false,
                ] );
@@ -1432,8 +1429,10 @@ class EditPage {
         * @return Status The resulting status object.
         */
        public function attemptSave( &$resultDetails = false ) {
+               global $wgUser;
+
                # Allow bots to exempt some edits from bot flagging
-               $bot = $this->context->getUser()->isAllowed( 'bot' ) && $this->bot;
+               $bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
                $status = $this->internalAttemptSave( $resultDetails, $bot );
 
                Hooks::run( 'EditPage::attemptSave:after', [ $this, $status, $resultDetails ] );
@@ -1451,6 +1450,8 @@ class EditPage {
         * @return bool False, if output is done, true if rest of the form should be displayed
         */
        private function handleStatus( Status $status, $resultDetails ) {
+               global $wgUser, $wgOut;
+
                /**
                 * @todo FIXME: once the interface for internalAttemptSave() is made
                 *   nicer, this should use the message in $status
@@ -1464,11 +1465,9 @@ class EditPage {
                        }
                }
 
-               $out = $this->context->getOutput();
-
                // "wpExtraQueryRedirect" is a hidden input to modify
                // after save URL and is not used by actual edit form
-               $request = $this->context->getRequest();
+               $request = RequestContext::getMain()->getRequest();
                $extraQueryRedirect = $request->getVal( 'wpExtraQueryRedirect' );
 
                switch ( $status->value ) {
@@ -1489,7 +1488,7 @@ class EditPage {
 
                        case self::AS_CANNOT_USE_CUSTOM_MODEL:
                        case self::AS_PARSE_ERROR:
-                               $out->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
                                return true;
 
                        case self::AS_SUCCESS_NEW_ARTICLE:
@@ -1502,7 +1501,7 @@ class EditPage {
                                        }
                                }
                                $anchor = isset( $resultDetails['sectionanchor'] ) ? $resultDetails['sectionanchor'] : '';
-                               $out->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
+                               $wgOut->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
                                return false;
 
                        case self::AS_SUCCESS_UPDATE:
@@ -1530,7 +1529,7 @@ class EditPage {
                                        }
                                }
 
-                               $out->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
+                               $wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
                                return false;
 
                        case self::AS_SPAM_ERROR:
@@ -1538,7 +1537,7 @@ class EditPage {
                                return false;
 
                        case self::AS_BLOCKED_PAGE_FOR_USER:
-                               throw new UserBlockedError( $this->context->getUser()->getBlock() );
+                               throw new UserBlockedError( $wgUser->getBlock() );
 
                        case self::AS_IMAGE_REDIRECT_ANON:
                        case self::AS_IMAGE_REDIRECT_LOGGED:
@@ -1599,7 +1598,7 @@ class EditPage {
 
                // Run new style post-section-merge edit filter
                if ( !Hooks::run( 'EditFilterMergedContent',
-                               [ $this->context, $content, $status, $this->summary,
+                               [ $this->mArticle->getContext(), $content, $status, $this->summary,
                                $user, $this->minoredit ] )
                ) {
                        # Error messages etc. could be handled within the hook...
@@ -1684,11 +1683,10 @@ class EditPage {
         * time.
         */
        function internalAttemptSave( &$result, $bot = false ) {
-               global $wgParser, $wgMaxArticleSize, $wgContentHandlerUseDB;
+               global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
+               global $wgContentHandlerUseDB;
 
                $status = Status::newGood();
-               $user = $this->context->getUser();
-               $request = $this->context->getRequest();
 
                if ( !Hooks::run( 'EditPage::attemptSave', [ $this ] ) ) {
                        wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
@@ -1697,11 +1695,11 @@ class EditPage {
                        return $status;
                }
 
-               $spam = $request->getText( 'wpAntispam' );
+               $spam = $wgRequest->getText( 'wpAntispam' );
                if ( $spam !== '' ) {
                        wfDebugLog(
                                'SimpleAntiSpam',
-                               $user->getName() .
+                               $wgUser->getName() .
                                ' editing "' .
                                $this->mTitle->getPrefixedText() .
                                '" submitted bogus field "' .
@@ -1730,9 +1728,9 @@ class EditPage {
                # Check image redirect
                if ( $this->mTitle->getNamespace() == NS_FILE &&
                        $textbox_content->isRedirect() &&
-                       !$user->isAllowed( 'upload' )
+                       !$wgUser->isAllowed( 'upload' )
                ) {
-                               $code = $user->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
+                               $code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
                                $status->setResult( false, $code );
 
                                return $status;
@@ -1757,7 +1755,7 @@ class EditPage {
                }
                if ( $match !== false ) {
                        $result['spam'] = $match;
-                       $ip = $request->getIP();
+                       $ip = $wgRequest->getIP();
                        $pdbk = $this->mTitle->getPrefixedDBkey();
                        $match = str_replace( "\n", '', $match );
                        wfDebugLog( 'SpamRegex', "$ip spam regex hit [[$pdbk]]: \"$match\"" );
@@ -1780,10 +1778,10 @@ class EditPage {
                        return $status;
                }
 
-               if ( $user->isBlockedFrom( $this->mTitle, false ) ) {
+               if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $user->spreadAnyEditBlock();
+                               $wgUser->spreadAnyEditBlock();
                        }
                        # Check block state against master, thus 'false'.
                        $status->setResult( false, self::AS_BLOCKED_PAGE_FOR_USER );
@@ -1798,8 +1796,8 @@ class EditPage {
                        return $status;
                }
 
-               if ( !$user->isAllowed( 'edit' ) ) {
-                       if ( $user->isAnon() ) {
+               if ( !$wgUser->isAllowed( 'edit' ) ) {
+                       if ( $wgUser->isAnon() ) {
                                $status->setResult( false, self::AS_READ_ONLY_PAGE_ANON );
                                return $status;
                        } else {
@@ -1815,7 +1813,7 @@ class EditPage {
                                $status->fatal( 'editpage-cannot-use-custom-model' );
                                $status->value = self::AS_CANNOT_USE_CUSTOM_MODEL;
                                return $status;
-                       } elseif ( !$user->isAllowed( 'editcontentmodel' ) ) {
+                       } elseif ( !$wgUser->isAllowed( 'editcontentmodel' ) ) {
                                $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL );
                                return $status;
 
@@ -1826,7 +1824,7 @@ class EditPage {
 
                if ( $this->changeTags ) {
                        $changeTagsStatus = ChangeTags::canAddTagsAccompanyingChange(
-                               $this->changeTags, $user );
+                               $this->changeTags, $wgUser );
                        if ( !$changeTagsStatus->isOK() ) {
                                $changeTagsStatus->value = self::AS_CHANGE_TAG_ERROR;
                                return $changeTagsStatus;
@@ -1838,7 +1836,7 @@ class EditPage {
                        $status->value = self::AS_READ_ONLY_PAGE;
                        return $status;
                }
-               if ( $user->pingLimiter() || $user->pingLimiter( 'linkpurge', 0 ) ) {
+               if ( $wgUser->pingLimiter() || $wgUser->pingLimiter( 'linkpurge', 0 ) ) {
                        $status->fatal( 'actionthrottledtext' );
                        $status->value = self::AS_RATE_LIMITED;
                        return $status;
@@ -1858,7 +1856,7 @@ class EditPage {
 
                if ( $new ) {
                        // Late check for create permission, just in case *PARANOIA*
-                       if ( !$this->mTitle->userCan( 'create', $user ) ) {
+                       if ( !$this->mTitle->userCan( 'create', $wgUser ) ) {
                                $status->fatal( 'nocreatetext' );
                                $status->value = self::AS_NO_CREATE_PERMISSION;
                                wfDebug( __METHOD__ . ": no create permission\n" );
@@ -1882,7 +1880,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $user ) ) {
+                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $wgUser ) ) {
                                return $status;
                        }
 
@@ -1918,7 +1916,7 @@ class EditPage {
                        ) {
                                $this->isConflict = true;
                                if ( $this->section == 'new' ) {
-                                       if ( $this->page->getUserText() == $user->getName() &&
+                                       if ( $this->page->getUserText() == $wgUser->getName() &&
                                                $this->page->getComment() == $this->newSectionSummary()
                                        ) {
                                                // Probably a duplicate submission of a new comment.
@@ -1934,7 +1932,7 @@ class EditPage {
                                } elseif ( $this->section == ''
                                        && Revision::userWasLastToEdit(
                                                DB_MASTER, $this->mTitle->getArticleID(),
-                                               $user->getId(), $this->edittime
+                                               $wgUser->getId(), $this->edittime
                                        )
                                ) {
                                        # Suppress edit conflict with self, except for section edits where merging is required.
@@ -2004,7 +2002,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $content, $status, $user ) ) {
+                       if ( !$this->runPostMergeFilters( $content, $status, $wgUser ) ) {
                                return $status;
                        }
 
@@ -2025,7 +2023,7 @@ class EditPage {
                                        return $status;
                                }
                        } elseif ( !$this->allowBlankSummary
-                               && !$content->equals( $this->getOriginalContent( $user ) )
+                               && !$content->equals( $this->getOriginalContent( $wgUser ) )
                                && !$content->isRedirect()
                                && md5( $this->summary ) == $this->autoSumm
                        ) {
@@ -2095,7 +2093,7 @@ class EditPage {
                        $this->summary,
                        $flags,
                        false,
-                       $user,
+                       $wgUser,
                        $content->getDefaultFormat(),
                        $this->changeTags
                );
@@ -2118,7 +2116,7 @@ class EditPage {
                $result['nullEdit'] = $doEditStatus->hasMessage( 'edit-no-change' );
                if ( $result['nullEdit'] ) {
                        // We don't know if it was a null edit until now, so increment here
-                       $user->pingLimiter( 'linkpurge' );
+                       $wgUser->pingLimiter( 'linkpurge' );
                }
                $result['redirect'] = $content->isRedirect();
 
@@ -2127,7 +2125,7 @@ class EditPage {
                // If the content model changed, add a log entry
                if ( $changingContentModel ) {
                        $this->addContentModelChangeLogEntry(
-                               $user,
+                               $wgUser,
                                $new ? false : $oldContentModel,
                                $this->contentModel,
                                $this->summary
@@ -2161,12 +2159,13 @@ class EditPage {
         * Register the change of watch status
         */
        protected function updateWatchlist() {
-               $user = $this->context->getUser();
+               global $wgUser;
 
-               if ( !$user->isLoggedIn() ) {
+               if ( !$wgUser->isLoggedIn() ) {
                        return;
                }
 
+               $user = $wgUser;
                $title = $this->mTitle;
                $watch = $this->watchthis;
                // Do this in its own transaction to reduce contention...
@@ -2281,32 +2280,29 @@ class EditPage {
        }
 
        function setHeaders() {
-               global $wgAjaxEditStash;
-
-               $out = $this->context->getOutput();
-               $user = $this->context->getUser();
+               global $wgOut, $wgUser, $wgAjaxEditStash;
 
-               $out->addModules( 'mediawiki.action.edit' );
-               $out->addModuleStyles( 'mediawiki.action.edit.styles' );
+               $wgOut->addModules( 'mediawiki.action.edit' );
+               $wgOut->addModuleStyles( 'mediawiki.action.edit.styles' );
 
-               if ( $user->getOption( 'showtoolbar' ) ) {
+               if ( $wgUser->getOption( 'showtoolbar' ) ) {
                        // The addition of default buttons is handled by getEditToolbar() which
                        // has its own dependency on this module. The call here ensures the module
                        // is loaded in time (it has position "top") for other modules to register
                        // buttons (e.g. extensions, gadgets, user scripts).
-                       $out->addModules( 'mediawiki.toolbar' );
+                       $wgOut->addModules( 'mediawiki.toolbar' );
                }
 
-               if ( $user->getOption( 'uselivepreview' ) ) {
-                       $out->addModules( 'mediawiki.action.edit.preview' );
+               if ( $wgUser->getOption( 'uselivepreview' ) ) {
+                       $wgOut->addModules( 'mediawiki.action.edit.preview' );
                }
 
-               if ( $user->getOption( 'useeditwarning' ) ) {
-                       $out->addModules( 'mediawiki.action.edit.editWarning' );
+               if ( $wgUser->getOption( 'useeditwarning' ) ) {
+                       $wgOut->addModules( 'mediawiki.action.edit.editWarning' );
                }
 
                # Enabled article-related sidebar, toplinks, etc.
-               $out->setArticleRelated( true );
+               $wgOut->setArticleRelated( true );
 
                $contextTitle = $this->getContextTitle();
                if ( $this->isConflict ) {
@@ -2329,10 +2325,10 @@ class EditPage {
                if ( $displayTitle === false ) {
                        $displayTitle = $contextTitle->getPrefixedText();
                }
-               $out->setPageTitle( wfMessage( $msg, $displayTitle ) );
+               $wgOut->setPageTitle( wfMessage( $msg, $displayTitle ) );
                # Transmit the name of the message to JavaScript for live preview
                # Keep Resources.php/mediawiki.action.edit.preview in sync with the possible keys
-               $out->addJsConfigVars( [
+               $wgOut->addJsConfigVars( [
                        'wgEditMessage' => $msg,
                        'wgAjaxEditStash' => $wgAjaxEditStash,
                ] );
@@ -2342,16 +2338,16 @@ class EditPage {
         * Show all applicable editing introductions
         */
        protected function showIntro() {
+               global $wgOut, $wgUser;
                if ( $this->suppressIntro ) {
                        return;
                }
 
-               $out = $this->context->getOutput();
                $namespace = $this->mTitle->getNamespace();
 
                if ( $namespace == NS_MEDIAWIKI ) {
                        # Show a warning if editing an interface message
-                       $out->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+                       $wgOut->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
                        # If this is a default message (but not css or js),
                        # show a hint that it is translatable on translatewiki.net
                        if ( !$this->mTitle->hasContentModel( CONTENT_MODEL_CSS )
@@ -2359,7 +2355,7 @@ class EditPage {
                        ) {
                                $defaultMessageText = $this->mTitle->getDefaultMessageText();
                                if ( $defaultMessageText !== false ) {
-                                       $out->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
+                                       $wgOut->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
                                                'translateinterface' );
                                }
                        }
@@ -2371,11 +2367,11 @@ class EditPage {
                                # there must be a description url to show a hint to shared repo
                                if ( $descUrl ) {
                                        if ( !$this->mTitle->exists() ) {
-                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
+                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
                                                                        'sharedupload-desc-create', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        } else {
-                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
+                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
                                                                        'sharedupload-desc-edit', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        }
@@ -2391,12 +2387,12 @@ class EditPage {
                        $ip = User::isIP( $username );
                        $block = Block::newFromTarget( $user, $user );
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
-                               $out->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
                                        [ 'userpage-userdoesnotexist', wfEscapeWikiText( $username ) ] );
                        } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) {
                                # Show log extract if the user is currently blocked
                                LogEventsList::showLogExtract(
-                                       $out,
+                                       $wgOut,
                                        'block',
                                        MWNamespace::getCanonicalName( NS_USER ) . ':' . $block->getTarget(),
                                        '',
@@ -2416,8 +2412,8 @@ class EditPage {
                        $helpLink = wfExpandUrl( Skin::makeInternalOrExternalUrl(
                                wfMessage( 'helppage' )->inContentLanguage()->text()
                        ) );
-                       if ( $this->context->getUser()->isLoggedIn() ) {
-                               $out->wrapWikiMsg(
+                       if ( $wgUser->isLoggedIn() ) {
+                               $wgOut->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletext plainlinks\">\n$1\n</div>",
                                        [
@@ -2426,7 +2422,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $out->wrapWikiMsg(
+                               $wgOut->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletextanon plainlinks\">\n$1\n</div>",
                                        [
@@ -2438,7 +2434,7 @@ class EditPage {
                }
                # Give a notice if the user is editing a deleted/moved page...
                if ( !$this->mTitle->exists() ) {
-                       LogEventsList::showLogExtract( $out, [ 'delete', 'move' ], $this->mTitle,
+                       LogEventsList::showLogExtract( $wgOut, [ 'delete', 'move' ], $this->mTitle,
                                '',
                                [
                                        'lim' => 10,
@@ -2459,8 +2455,9 @@ class EditPage {
                if ( $this->editintro ) {
                        $title = Title::newFromText( $this->editintro );
                        if ( $title instanceof Title && $title->exists() && $title->userCan( 'read' ) ) {
+                               global $wgOut;
                                // Added using template syntax, to take <noinclude>'s into account.
-                               $this->context->getOutput()->addWikiTextTitleTidy(
+                               $wgOut->addWikiTextTitleTidy(
                                        '<div class="mw-editintro">{{:' . $title->getFullText() . '}}</div>',
                                        $this->mTitle
                                );
@@ -2494,8 +2491,7 @@ class EditPage {
                }
 
                if ( !$this->isSupportedContentModel( $content->getModel() ) ) {
-                       throw new MWException( 'This content model is not supported: '
-                               . ContentHandler::getLocalizedName( $content->getModel() ) );
+                       throw new MWException( 'This content model is not supported: ' . $content->getModel() );
                }
 
                return $content->serialize( $this->contentFormat );
@@ -2526,8 +2522,7 @@ class EditPage {
                        $this->contentModel, $this->contentFormat );
 
                if ( !$this->isSupportedContentModel( $content->getModel() ) ) {
-                       throw new MWException( 'This content model is not supported: '
-                               . ContentHandler::getLocalizedName( $content->getModel() ) );
+                       throw new MWException( 'This content model is not supported: ' . $content->getModel() );
                }
 
                return $content;
@@ -2542,6 +2537,8 @@ class EditPage {
         * use the EditPage::showEditForm:fields hook instead.
         */
        function showEditForm( $formCallback = null ) {
+               global $wgOut, $wgUser;
+
                # need to parse the preview early so that we know which templates are used,
                # otherwise users with "show preview after edit box" will get a blank list
                # we parse this near the beginning so that setHeaders can do the title
@@ -2551,8 +2548,7 @@ class EditPage {
                        $previewOutput = $this->getPreviewText();
                }
 
-               $out = $this->context->getOutput();
-               Hooks::run( 'EditPage::showEditForm:initial', [ &$this, &$out ] );
+               Hooks::run( 'EditPage::showEditForm:initial', [ &$this, &$wgOut ] );
 
                $this->setHeaders();
 
@@ -2560,14 +2556,13 @@ class EditPage {
                        return;
                }
 
-               $out->addHTML( $this->editFormPageTop );
+               $wgOut->addHTML( $this->editFormPageTop );
 
-               $user = $this->context->getUser();
-               if ( $user->getOption( 'previewontop' ) ) {
+               if ( $wgUser->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, true );
                }
 
-               $out->addHTML( $this->editFormTextTop );
+               $wgOut->addHTML( $this->editFormTextTop );
 
                $showToolbar = true;
                if ( $this->wasDeletedSinceLastEdit() ) {
@@ -2576,14 +2571,14 @@ class EditPage {
                                // Add an confirmation checkbox and explanation.
                                $showToolbar = false;
                        } else {
-                               $out->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
                                        'deletedwhileediting' );
                        }
                }
 
                // @todo add EditForm plugin interface and use it here!
                //       search for textarea1 and textares2, and allow EditForm to override all uses.
-               $out->addHTML( Html::openElement(
+               $wgOut->addHTML( Html::openElement(
                        'form',
                        [
                                'id' => self::EDITFORM_ID,
@@ -2596,11 +2591,11 @@ class EditPage {
 
                if ( is_callable( $formCallback ) ) {
                        wfWarn( 'The $formCallback parameter to ' . __METHOD__ . 'is deprecated' );
-                       call_user_func_array( $formCallback, [ &$out ] );
+                       call_user_func_array( $formCallback, [ &$wgOut ] );
                }
 
                // Add an empty field to trip up spambots
-               $out->addHTML(
+               $wgOut->addHTML(
                        Xml::openElement( 'div', [ 'id' => 'antispam-container', 'style' => 'display: none;' ] )
                        . Html::rawElement(
                                'label',
@@ -2619,7 +2614,7 @@ class EditPage {
                        . Xml::closeElement( 'div' )
                );
 
-               Hooks::run( 'EditPage::showEditForm:fields', [ &$this, &$out ] );
+               Hooks::run( 'EditPage::showEditForm:fields', [ &$this, &$wgOut ] );
 
                // Put these up at the top to ensure they aren't lost on early form submission
                $this->showFormBeforeText();
@@ -2633,7 +2628,7 @@ class EditPage {
                        $key = $comment === ''
                                ? 'confirmrecreate-noreason'
                                : 'confirmrecreate';
-                       $out->addHTML(
+                       $wgOut->addHTML(
                                '<div class="mw-confirm-recreate">' .
                                        wfMessage( $key, $username, "<nowiki>$comment</nowiki>" )->parse() .
                                Xml::checkLabel( wfMessage( 'recreate' )->text(), 'wpRecreate', 'wpRecreate', false,
@@ -2645,7 +2640,7 @@ class EditPage {
 
                # When the summary is hidden, also hide them on preview/show changes
                if ( $this->nosummary ) {
-                       $out->addHTML( Html::hidden( 'nosummary', true ) );
+                       $wgOut->addHTML( Html::hidden( 'nosummary', true ) );
                }
 
                # If a blank edit summary was previously provided, and the appropriate
@@ -2656,15 +2651,15 @@ class EditPage {
                # For a bit more sophisticated detection of blank summaries, hash the
                # automatic one and pass that in the hidden field wpAutoSummary.
                if ( $this->missingSummary || ( $this->section == 'new' && $this->nosummary ) ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
                }
 
                if ( $this->undidRev ) {
-                       $out->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
+                       $wgOut->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
                }
 
                if ( $this->selfRedirect ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
                }
 
                if ( $this->hasPresetSummary ) {
@@ -2675,27 +2670,27 @@ class EditPage {
                }
 
                $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
-               $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
+               $wgOut->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
 
-               $out->addHTML( Html::hidden( 'oldid', $this->oldid ) );
-               $out->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
+               $wgOut->addHTML( Html::hidden( 'oldid', $this->oldid ) );
+               $wgOut->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
 
-               $out->addHTML( Html::hidden( 'format', $this->contentFormat ) );
-               $out->addHTML( Html::hidden( 'model', $this->contentModel ) );
+               $wgOut->addHTML( Html::hidden( 'format', $this->contentFormat ) );
+               $wgOut->addHTML( Html::hidden( 'model', $this->contentModel ) );
 
                if ( $this->section == 'new' ) {
                        $this->showSummaryInput( true, $this->summary );
-                       $out->addHTML( $this->getSummaryPreview( true, $this->summary ) );
+                       $wgOut->addHTML( $this->getSummaryPreview( true, $this->summary ) );
                }
 
-               $out->addHTML( $this->editFormTextBeforeContent );
+               $wgOut->addHTML( $this->editFormTextBeforeContent );
 
-               if ( !$this->isCssJsSubpage && $showToolbar && $user->getOption( 'showtoolbar' ) ) {
-                       $out->addHTML( EditPage::getEditToolbar( $this->mTitle ) );
+               if ( !$this->isCssJsSubpage && $showToolbar && $wgUser->getOption( 'showtoolbar' ) ) {
+                       $wgOut->addHTML( EditPage::getEditToolbar( $this->mTitle ) );
                }
 
                if ( $this->blankArticle ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
                }
 
                if ( $this->isConflict ) {
@@ -2713,7 +2708,7 @@ class EditPage {
                        $this->showContentForm();
                }
 
-               $out->addHTML( $this->editFormTextAfterContent );
+               $wgOut->addHTML( $this->editFormTextAfterContent );
 
                $this->showStandardInputs();
 
@@ -2723,19 +2718,19 @@ class EditPage {
 
                $this->showEditTools();
 
-               $out->addHTML( $this->editFormTextAfterTools . "\n" );
+               $wgOut->addHTML( $this->editFormTextAfterTools . "\n" );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
                        Linker::formatTemplates( $this->getTemplates(), $this->preview, $this->section != '' ) ) );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
                        Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) );
 
                if ( $this->mParserOutput ) {
-                       $out->setLimitReportData( $this->mParserOutput->getLimitReportData() );
+                       $wgOut->setLimitReportData( $this->mParserOutput->getLimitReportData() );
                }
 
-               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
                if ( $this->isConflict ) {
                        try {
@@ -2748,7 +2743,7 @@ class EditPage {
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
 
@@ -2762,14 +2757,14 @@ class EditPage {
                } else {
                        $mode = 'text';
                }
-               $out->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
+               $wgOut->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
 
                // Marker for detecting truncated form data.  This must be the last
                // parameter sent in order to be of use, so do not move me.
-               $out->addHTML( Html::hidden( 'wpUltimateParam', true ) );
-               $out->addHTML( $this->editFormTextBottom . "\n</form>\n" );
+               $wgOut->addHTML( Html::hidden( 'wpUltimateParam', true ) );
+               $wgOut->addHTML( $this->editFormTextBottom . "\n</form>\n" );
 
-               if ( !$user->getOption( 'previewontop' ) ) {
+               if ( !$wgUser->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, false );
                }
 
@@ -2795,23 +2790,21 @@ class EditPage {
         * @return bool
         */
        protected function showHeader() {
-               global $wgMaxArticleSize, $wgAllowUserCss, $wgAllowUserJs;
-
-               $out = $this->context->getOutput();
-               $user = $this->context->getUser();
+               global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
+               global $wgAllowUserCss, $wgAllowUserJs;
 
                if ( $this->mTitle->isTalkPage() ) {
-                       $out->addWikiMsg( 'talkpagetext' );
+                       $wgOut->addWikiMsg( 'talkpagetext' );
                }
 
                // Add edit notices
                $editNotices = $this->mTitle->getEditNotices( $this->oldid );
                if ( count( $editNotices ) ) {
-                       $out->addHTML( implode( "\n", $editNotices ) );
+                       $wgOut->addHTML( implode( "\n", $editNotices ) );
                } else {
                        $msg = wfMessage( 'editnotice-notext' );
                        if ( !$msg->isDisabled() ) {
-                               $out->addHTML(
+                               $wgOut->addHTML(
                                        '<div class="mw-editnotice-notext">'
                                        . $msg->parseAsBlock()
                                        . '</div>'
@@ -2820,14 +2813,14 @@ class EditPage {
                }
 
                if ( $this->isConflict ) {
-                       $out->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
+                       $wgOut->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
                        $this->editRevId = $this->page->getLatest();
                } else {
                        if ( $this->section != '' && !$this->isSectionEditSupported() ) {
                                // We use $this->section to much before this and getVal('wgSection') directly in other places
                                // at this point we can't reset $this->section to '' to fallback to non-section editing.
                                // Someone is welcome to try refactoring though
-                               $out->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
+                               $wgOut->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
                                return false;
                        }
 
@@ -2841,31 +2834,31 @@ class EditPage {
                        }
 
                        if ( $this->missingComment ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
                        }
 
                        if ( $this->missingSummary && $this->section != 'new' ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingsummary'>\n$1\n</div>", 'missingsummary' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingsummary'>\n$1\n</div>", 'missingsummary' );
                        }
 
                        if ( $this->missingSummary && $this->section == 'new' ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
                        }
 
                        if ( $this->blankArticle ) {
-                               $out->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
                        }
 
                        if ( $this->selfRedirect ) {
-                               $out->wrapWikiMsg( "<div id='mw-selfredirect'>\n$1\n</div>", 'selfredirect' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-selfredirect'>\n$1\n</div>", 'selfredirect' );
                        }
 
                        if ( $this->hookError !== '' ) {
-                               $out->addWikiText( $this->hookError );
+                               $wgOut->addWikiText( $this->hookError );
                        }
 
                        if ( !$this->checkUnicodeCompliantBrowser() ) {
-                               $out->addWikiMsg( 'nonunicodebrowser' );
+                               $wgOut->addWikiMsg( 'nonunicodebrowser' );
                        }
 
                        if ( $this->section != 'new' ) {
@@ -2873,13 +2866,13 @@ class EditPage {
                                if ( $revision ) {
                                        // Let sysop know that this will make private content public if saved
 
-                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $user ) ) {
-                                               $out->wrapWikiMsg(
+                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $wgUser ) ) {
+                                               $wgOut->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-permission'
                                                );
                                        } elseif ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
-                                               $out->wrapWikiMsg(
+                                               $wgOut->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-view'
                                                );
@@ -2887,25 +2880,25 @@ class EditPage {
 
                                        if ( !$revision->isCurrent() ) {
                                                $this->mArticle->setOldSubtitle( $revision->getId() );
-                                               $out->addWikiMsg( 'editingold' );
+                                               $wgOut->addWikiMsg( 'editingold' );
                                        }
                                } elseif ( $this->mTitle->exists() ) {
                                        // Something went wrong
 
-                                       $out->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
+                                       $wgOut->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
                                                [ 'missing-revision', $this->oldid ] );
                                }
                        }
                }
 
                if ( wfReadOnly() ) {
-                       $out->wrapWikiMsg(
+                       $wgOut->wrapWikiMsg(
                                "<div id=\"mw-read-only-warning\">\n$1\n</div>",
                                [ 'readonlywarning', wfReadOnlyReason() ]
                        );
-               } elseif ( $user->isAnon() ) {
+               } elseif ( $wgUser->isAnon() ) {
                        if ( $this->formtype != 'preview' ) {
-                               $out->wrapWikiMsg(
+                               $wgOut->wrapWikiMsg(
                                        "<div id='mw-anon-edit-warning' class='warningbox'>\n$1\n</div>",
                                        [ 'anoneditwarning',
                                                // Log-in link
@@ -2919,7 +2912,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $out->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
+                               $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
                                        'anonpreviewwarning'
                                );
                        }
@@ -2927,25 +2920,25 @@ class EditPage {
                        if ( $this->isCssJsSubpage ) {
                                # Check the skin exists
                                if ( $this->isWrongCaseCssJsPage ) {
-                                       $out->wrapWikiMsg(
+                                       $wgOut->wrapWikiMsg(
                                                "<div class='error' id='mw-userinvalidcssjstitle'>\n$1\n</div>",
                                                [ 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ]
                                        );
                                }
-                               if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) {
-                                       $out->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
+                               if ( $this->getTitle()->isSubpageOf( $wgUser->getUserPage() ) ) {
+                                       $wgOut->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
                                                $this->isCssSubpage ? 'usercssispublic' : 'userjsispublic'
                                        );
                                        if ( $this->formtype !== 'preview' ) {
                                                if ( $this->isCssSubpage && $wgAllowUserCss ) {
-                                                       $out->wrapWikiMsg(
+                                                       $wgOut->wrapWikiMsg(
                                                                "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
                                                                [ 'usercssyoucanpreview' ]
                                                        );
                                                }
 
                                                if ( $this->isJsSubpage && $wgAllowUserJs ) {
-                                                       $out->wrapWikiMsg(
+                                                       $wgOut->wrapWikiMsg(
                                                                "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
                                                                [ 'userjsyoucanpreview' ]
                                                        );
@@ -2965,7 +2958,7 @@ class EditPage {
                                # Then it must be protected based on static groups (regular)
                                $noticeMsg = 'protectedpagewarning';
                        }
-                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
                                [ 'lim' => 1, 'msgKey' => [ $noticeMsg ] ] );
                }
                if ( $this->mTitle->isCascadeProtected() ) {
@@ -2981,10 +2974,10 @@ class EditPage {
                                }
                        }
                        $notice .= '</div>';
-                       $out->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
+                       $wgOut->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
                }
                if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
-                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
                                [ 'lim' => 1,
                                        'showIfEmpty' => false,
                                        'msgKey' => [ 'titleprotectedwarning' ],
@@ -2995,21 +2988,20 @@ class EditPage {
                        $this->contentLength = strlen( $this->textbox1 );
                }
 
-               $lang = $this->context->getLanguage();
                if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) {
-                       $out->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
+                       $wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
                                [
                                        'longpageerror',
-                                       $lang->formatNum( round( $this->contentLength / 1024, 3 ) ),
-                                       $lang->formatNum( $wgMaxArticleSize )
+                                       $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ),
+                                       $wgLang->formatNum( $wgMaxArticleSize )
                                ]
                        );
                } else {
                        if ( !wfMessage( 'longpage-hint' )->isDisabled() ) {
-                               $out->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
                                        [
                                                'longpage-hint',
-                                               $lang->formatSize( strlen( $this->textbox1 ) ),
+                                               $wgLang->formatSize( strlen( $this->textbox1 ) ),
                                                strlen( $this->textbox1 )
                                        ]
                                );
@@ -3074,6 +3066,7 @@ class EditPage {
         * @param string $summary The text of the summary to display
         */
        protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
+               global $wgOut;
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                if ( $isSubjectPreview ) {
@@ -3092,7 +3085,7 @@ class EditPage {
                        [ 'class' => $summaryClass ],
                        []
                );
-               $this->context->getOutput()->addHTML( "{$label} {$input}" );
+               $wgOut->addHTML( "{$label} {$input}" );
        }
 
        /**
@@ -3124,9 +3117,9 @@ class EditPage {
        }
 
        protected function showFormBeforeText() {
+               global $wgOut;
                $section = htmlspecialchars( $this->section );
-               $out = $this->context->getOutput();
-               $out->addHTML( <<<HTML
+               $wgOut->addHTML( <<<HTML
 <input type='hidden' value="{$section}" name="wpSection"/>
 <input type='hidden' value="{$this->starttime}" name="wpStarttime" />
 <input type='hidden' value="{$this->edittime}" name="wpEdittime" />
@@ -3136,11 +3129,12 @@ class EditPage {
 HTML
                );
                if ( !$this->checkUnicodeCompliantBrowser() ) {
-                       $out->addHTML( Html::hidden( 'safemode', '1' ) );
+                       $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
                }
        }
 
        protected function showFormAfterText() {
+               global $wgOut, $wgUser;
                /**
                 * To make it harder for someone to slip a user a page
                 * which submits an edit form to the wiki without their
@@ -3153,10 +3147,7 @@ HTML
                 * include the constant suffix to prevent editing from
                 * broken text-mangling proxies.
                 */
-               $token = $this->context->getUser()->getEditToken();
-               $this->context->getOutput()->addHTML(
-                       "\n" . Html::hidden( "wpEditToken", $token ) . "\n"
-               );
+               $wgOut->addHTML( "\n" . Html::hidden( "wpEditToken", $wgUser->getEditToken() ) . "\n" );
        }
 
        /**
@@ -3226,6 +3217,8 @@ HTML
        }
 
        protected function showTextbox( $text, $name, $customAttribs = [] ) {
+               global $wgOut, $wgUser;
+
                $wikitext = $this->safeUnicodeOutput( $text );
                if ( strval( $wikitext ) !== '' ) {
                        // Ensure there's a newline at the end, otherwise adding lines
@@ -3235,12 +3228,11 @@ HTML
                        $wikitext .= "\n";
                }
 
-               $user = $this->context->getUser();
                $attribs = $customAttribs + [
                        'accesskey' => ',',
                        'id' => $name,
-                       'cols' => $user->getIntOption( 'cols' ),
-                       'rows' => $user->getIntOption( 'rows' ),
+                       'cols' => $wgUser->getIntOption( 'cols' ),
+                       'rows' => $wgUser->getIntOption( 'rows' ),
                        // Avoid PHP notices when appending preferences
                        // (appending allows customAttribs['style'] to still work).
                        'style' => ''
@@ -3250,10 +3242,11 @@ HTML
                $attribs['lang'] = $pageLang->getHtmlCode();
                $attribs['dir'] = $pageLang->getDir();
 
-               $this->context->getOutput()->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
+               $wgOut->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
        }
 
        protected function displayPreviewArea( $previewOutput, $isOnTop = false ) {
+               global $wgOut;
                $classes = [];
                if ( $isOnTop ) {
                        $classes[] = 'ontop';
@@ -3265,8 +3258,7 @@ HTML
                        $attribs['style'] = 'display: none;';
                }
 
-               $out = $this->context->getOutput();
-               $out->addHTML( Xml::openElement( 'div', $attribs ) );
+               $wgOut->addHTML( Xml::openElement( 'div', $attribs ) );
 
                if ( $this->formtype == 'preview' ) {
                        $this->showPreview( $previewOutput );
@@ -3275,10 +3267,10 @@ HTML
                        $pageViewLang = $this->mTitle->getPageViewLanguage();
                        $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
                                'class' => 'mw-content-' . $pageViewLang->getDir() ];
-                       $out->addHTML( Html::rawElement( 'div', $attribs ) );
+                       $wgOut->addHTML( Html::rawElement( 'div', $attribs ) );
                }
 
-               $out->addHTML( '</div>' );
+               $wgOut->addHTML( '</div>' );
 
                if ( $this->formtype == 'diff' ) {
                        try {
@@ -3290,7 +3282,7 @@ HTML
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
        }
@@ -3302,14 +3294,14 @@ HTML
         * @param string $text The HTML to be output for the preview.
         */
        protected function showPreview( $text ) {
+               global $wgOut;
                if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
                        $this->mArticle->openShowCategory();
                }
-               $out = $this->context->getOutput();
                # This hook seems slightly odd here, but makes things more
                # consistent for extensions.
-               Hooks::run( 'OutputPageBeforeHTML', [ &$out, &$text ] );
-               $out->addHTML( $text );
+               Hooks::run( 'OutputPageBeforeHTML', [ &$wgOut, &$text ] );
+               $wgOut->addHTML( $text );
                if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
                        $this->mArticle->closeShowCategory();
                }
@@ -3323,7 +3315,7 @@ HTML
         * save and then make a comparison.
         */
        function showDiff() {
-               global $wgContLang;
+               global $wgUser, $wgContLang, $wgOut;
 
                $oldtitlemsg = 'currentrev';
                # if message does not exist, show diff against the preloaded default
@@ -3354,9 +3346,8 @@ HTML
                        ContentHandler::runLegacyHooks( 'EditPageGetDiffText', [ $this, &$newContent ] );
                        Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] );
 
-                       $user = $this->context->getUser();
-                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
-                       $newContent = $newContent->preSaveTransform( $this->mTitle, $user, $popts );
+                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+                       $newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
                }
 
                if ( ( $oldContent && !$oldContent->isEmpty() ) || ( $newContent && !$newContent->isEmpty() ) ) {
@@ -3380,7 +3371,7 @@ HTML
                        $difftext = '';
                }
 
-               $this->context->getOutput()->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
+               $wgOut->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
        }
 
        /**
@@ -3389,7 +3380,8 @@ HTML
        protected function showHeaderCopyrightWarning() {
                $msg = 'editpage-head-copy-warn';
                if ( !wfMessage( $msg )->isDisabled() ) {
-                       $this->context->getOutput()->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
+                       global $wgOut;
+                       $wgOut->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
                                'editpage-head-copy-warn' );
                }
        }
@@ -3406,15 +3398,16 @@ HTML
                $msg = 'editpage-tos-summary';
                Hooks::run( 'EditPageTosSummary', [ $this->mTitle, &$msg ] );
                if ( !wfMessage( $msg )->isDisabled() ) {
-                       $out = $this->context->getOutput();
-                       $out->addHTML( '<div class="mw-tos-summary">' );
-                       $out->addWikiMsg( $msg );
-                       $out->addHTML( '</div>' );
+                       global $wgOut;
+                       $wgOut->addHTML( '<div class="mw-tos-summary">' );
+                       $wgOut->addWikiMsg( $msg );
+                       $wgOut->addHTML( '</div>' );
                }
        }
 
        protected function showEditTools() {
-               $this->context->getOutput()->addHTML( '<div class="mw-editTools">' .
+               global $wgOut;
+               $wgOut->addHTML( '<div class="mw-editTools">' .
                        wfMessage( 'edittools' )->inContentLanguage()->parse() .
                        '</div>' );
        }
@@ -3474,24 +3467,24 @@ HTML
        }
 
        protected function showStandardInputs( &$tabindex = 2 ) {
-               $out = $this->context->getOutput();
-               $out->addHTML( "<div class='editOptions'>\n" );
+               global $wgOut;
+               $wgOut->addHTML( "<div class='editOptions'>\n" );
 
                if ( $this->section != 'new' ) {
                        $this->showSummaryInput( false, $this->summary );
-                       $out->addHTML( $this->getSummaryPreview( false, $this->summary ) );
+                       $wgOut->addHTML( $this->getSummaryPreview( false, $this->summary ) );
                }
 
                $checkboxes = $this->getCheckboxes( $tabindex,
                        [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ] );
-               $out->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
+               $wgOut->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
 
                // Show copyright warning.
-               $out->addWikiText( $this->getCopywarn() );
-               $out->addHTML( $this->editFormTextAfterWarn );
+               $wgOut->addWikiText( $this->getCopywarn() );
+               $wgOut->addHTML( $this->editFormTextAfterWarn );
 
-               $out->addHTML( "<div class='editButtons'>\n" );
-               $out->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
+               $wgOut->addHTML( "<div class='editButtons'>\n" );
+               $wgOut->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
 
                $cancel = $this->getCancelLink();
                if ( $cancel !== '' ) {
@@ -3511,13 +3504,13 @@ HTML
                        wfMessage( 'word-separator' )->escaped() .
                        wfMessage( 'newwindow' )->parse();
 
-               $out->addHTML( "        <span class='cancelLink'>{$cancel}</span>\n" );
-               $out->addHTML( "        <span class='editHelp'>{$edithelp}</span>\n" );
-               $out->addHTML( "</div><!-- editButtons -->\n" );
+               $wgOut->addHTML( "      <span class='cancelLink'>{$cancel}</span>\n" );
+               $wgOut->addHTML( "      <span class='editHelp'>{$edithelp}</span>\n" );
+               $wgOut->addHTML( "</div><!-- editButtons -->\n" );
 
-               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $out, &$tabindex ] );
+               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $wgOut, &$tabindex ] );
 
-               $out->addHTML( "</div><!-- editOptions -->\n" );
+               $wgOut->addHTML( "</div><!-- editOptions -->\n" );
        }
 
        /**
@@ -3525,9 +3518,10 @@ HTML
         * If you want to use another entry point to this function, be careful.
         */
        protected function showConflict() {
-               $out = $this->context->getOutput();
-               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$out ] ) ) {
-                       $stats = $this->context->getStats();
+               global $wgOut;
+
+               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$wgOut ] ) ) {
+                       $stats = $wgOut->getContext()->getStats();
                        $stats->increment( 'edit.failures.conflict' );
                        // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
                        if (
@@ -3537,7 +3531,7 @@ HTML
                                $stats->increment( 'edit.failures.conflict.byNamespaceId.' . $this->mTitle->getNamespace() );
                        }
 
-                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
 
                        $content1 = $this->toEditContent( $this->textbox1 );
                        $content2 = $this->toEditContent( $this->textbox2 );
@@ -3550,7 +3544,7 @@ HTML
                                wfMessage( 'storedversion' )->text()
                        );
 
-                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                        $this->showTextbox2();
                }
        }
@@ -3663,10 +3657,10 @@ HTML
         * @return string
         */
        function getPreviewText() {
-               global $wgRawHtml, $wgAllowUserCss, $wgAllowUserJs;
+               global $wgOut, $wgRawHtml, $wgLang;
+               global $wgAllowUserCss, $wgAllowUserJs;
 
-               $stats = $this->context->getStats();
-               $out = $this->context->getOutput();
+               $stats = $wgOut->getContext()->getStats();
 
                if ( $wgRawHtml && !$this->mTokenOk ) {
                        // Could be an offsite preview attempt. This is very unsafe if
@@ -3676,7 +3670,7 @@ HTML
                                // Do not put big scary notice, if previewing the empty
                                // string, which happens when you initially edit
                                // a category page, due to automatic preview-on-open.
-                               $parsedNote = $out->parse( "<div class='previewnote'>" .
+                               $parsedNote = $wgOut->parse( "<div class='previewnote'>" .
                                        wfMessage( 'session_fail_preview_html' )->text() . "</div>", true, /* interface */true );
                        }
                        $stats->increment( 'edit.failures.session_loss' );
@@ -3698,7 +3692,7 @@ HTML
 
                        # provide a anchor link to the editform
                        $continueEditing = '<span class="mw-continue-editing">' .
-                               '[[#' . self::EDITFORM_ID . '|' . $this->context->getLanguage()->getArrow() . ' ' .
+                               '[[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' .
                                wfMessage( 'continue-editing' )->text() . ']]</span>';
                        if ( $this->mTriedSave && !$this->mTokenOk ) {
                                if ( $this->mTokenOkExceptSuffix ) {
@@ -3764,7 +3758,7 @@ HTML
                        $parserOutput = $parserResult['parserOutput'];
                        $previewHTML = $parserResult['html'];
                        $this->mParserOutput = $parserOutput;
-                       $out->addParserOutputMetadata( $parserOutput );
+                       $wgOut->addParserOutputMetadata( $parserOutput );
 
                        if ( count( $parserOutput->getWarnings() ) ) {
                                $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
@@ -3790,7 +3784,7 @@ HTML
 
                $previewhead = "<div class='previewnote'>\n" .
                        '<h2 id="mw-previewheader">' . wfMessage( 'preview' )->escaped() . "</h2>" .
-                       $out->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
+                       $wgOut->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
 
                $pageViewLang = $this->mTitle->getPageViewLanguage();
                $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
@@ -3805,7 +3799,7 @@ HTML
         * @return ParserOptions
         */
        protected function getPreviewParserOptions() {
-               $parserOptions = $this->page->makeParserOptions( $this->context );
+               $parserOptions = $this->page->makeParserOptions( $this->mArticle->getContext() );
                $parserOptions->setIsPreview( true );
                $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
                $parserOptions->enableLimitReport();
@@ -3822,11 +3816,11 @@ HTML
         *   - html: The HTML to be displayed
         */
        protected function doPreviewParse( Content $content ) {
-               $user = $this->context->getUser();
+               global $wgUser;
                $parserOptions = $this->getPreviewParserOptions();
-               $pstContent = $content->preSaveTransform( $this->mTitle, $user, $parserOptions );
+               $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions );
                $scopedCallback = $parserOptions->setupFakeRevision(
-                       $this->mTitle, $pstContent, $user );
+                       $this->mTitle, $pstContent, $wgUser );
                $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions );
                ScopedCallback::consume( $scopedCallback );
                $parserOutput->setEditSectionTokens( false ); // no section edit links
@@ -4002,16 +3996,15 @@ HTML
         * @return array
         */
        public function getCheckboxes( &$tabindex, $checked ) {
-               global $wgUseMediaWikiUIEverywhere;
+               global $wgUser, $wgUseMediaWikiUIEverywhere;
 
                $checkboxes = [];
-               $user = $this->context->getUser();
 
                // don't show the minor edit checkbox if it's a new page or section
                if ( !$this->isNew ) {
                        $checkboxes['minor'] = '';
                        $minorLabel = wfMessage( 'minoredit' )->parse();
-                       if ( $user->isAllowed( 'minoredit' ) ) {
+                       if ( $wgUser->isAllowed( 'minoredit' ) ) {
                                $attribs = [
                                        'tabindex' => ++$tabindex,
                                        'accesskey' => wfMessage( 'accesskey-minoredit' )->text(),
@@ -4035,7 +4028,7 @@ HTML
 
                $watchLabel = wfMessage( 'watchthis' )->parse();
                $checkboxes['watch'] = '';
-               if ( $user->isLoggedIn() ) {
+               if ( $wgUser->isLoggedIn() ) {
                        $attribs = [
                                'tabindex' => ++$tabindex,
                                'accesskey' => wfMessage( 'accesskey-watch' )->text(),
@@ -4069,11 +4062,14 @@ HTML
        public function getEditButtons( &$tabindex ) {
                $buttons = [];
 
-               $labelAsPublish = $this->mArticle->getContext()->getConfig()->get( 'EditButtonPublishNotSave' );
+               $labelAsPublish =
+                       $this->mArticle->getContext()->getConfig()->get( 'EditSubmitButtonLabelPublish' );
+
+               // Can't use $this->isNew as that's also true if we're adding a new section to an extant page
                if ( $labelAsPublish ) {
-                       $buttonLabelKey = $this->isNew ? 'publishpage' : 'publishchanges';
+                       $buttonLabelKey = !$this->mTitle->exists() ? 'publishpage' : 'publishchanges';
                } else {
-                       $buttonLabelKey = $this->isNew ? 'savearticle' : 'savechanges';
+                       $buttonLabelKey = !$this->mTitle->exists() ? 'savearticle' : 'savechanges';
                }
                $buttonLabel = wfMessage( $buttonLabelKey )->text();
                $attribs = [
@@ -4110,14 +4106,15 @@ HTML
         * they have attempted to edit a nonexistent section.
         */
        function noSuchSectionPage() {
-               $out = $this->context->getOutput();
-               $out->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
+               global $wgOut;
+
+               $wgOut->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
 
                $res = wfMessage( 'nosuchsectiontext', $this->section )->parseAsBlock();
                Hooks::run( 'EditPageNoSuchSection', [ &$this, &$res ] );
-               $out->addHTML( $res );
+               $wgOut->addHTML( $res );
 
-               $out->returnToMain( false, $this->mTitle );
+               $wgOut->returnToMain( false, $this->mTitle );
        }
 
        /**
@@ -4126,28 +4123,28 @@ HTML
         * @param string|array|bool $match Text (or array of texts) which triggered one or more filters
         */
        public function spamPageWithContent( $match = false ) {
+               global $wgOut, $wgLang;
                $this->textbox2 = $this->textbox1;
 
                if ( is_array( $match ) ) {
-                       $match = $this->context->getLanguage()->listToText( $match );
+                       $match = $wgLang->listToText( $match );
                }
-               $out = $this->context->getOutput();
-               $out->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
+               $wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
 
-               $out->addHTML( '<div id="spamprotected">' );
-               $out->addWikiMsg( 'spamprotectiontext' );
+               $wgOut->addHTML( '<div id="spamprotected">' );
+               $wgOut->addWikiMsg( 'spamprotectiontext' );
                if ( $match ) {
-                       $out->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
+                       $wgOut->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
                }
-               $out->addHTML( '</div>' );
+               $wgOut->addHTML( '</div>' );
 
-               $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
                $this->showDiff();
 
-               $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                $this->showTextbox2();
 
-               $out->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
+               $wgOut->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
        }
 
        /**
@@ -4157,9 +4154,9 @@ HTML
         * @return bool
         */
        private function checkUnicodeCompliantBrowser() {
-               global $wgBrowserBlackList;
+               global $wgBrowserBlackList, $wgRequest;
 
-               $currentbrowser = $this->context->getRequest()->getHeader( 'User-Agent' );
+               $currentbrowser = $wgRequest->getHeader( 'User-Agent' );
                if ( $currentbrowser === false ) {
                        // No User-Agent header sent? Trust it by default...
                        return true;
index 5e540b9..2b38a96 100644 (file)
@@ -316,7 +316,7 @@ class Linker {
        /**
         * @since 1.16.3
         * @param LinkTarget $target
-        * @return LinkTarget|Title You will get back the same type you passed in, or a Title object
+        * @return LinkTarget
         */
        public static function normaliseSpecialPage( LinkTarget $target ) {
                if ( $target->getNamespace() == NS_SPECIAL ) {
@@ -324,7 +324,7 @@ class Linker {
                        if ( !$name ) {
                                return $target;
                        }
-                       $ret = SpecialPage::getTitleFor( $name, $subpage, $target->getFragment() );
+                       $ret = SpecialPage::getTitleValueFor( $name, $subpage, $target->getFragment() );
                        return $ret;
                } else {
                        return $target;
@@ -428,47 +428,43 @@ class Linker {
                        return self::link( $title );
                }
 
-               // Shortcuts
-               $fp =& $frameParams;
-               $hp =& $handlerParams;
-
                // Clean up parameters
-               $page = isset( $hp['page'] ) ? $hp['page'] : false;
-               if ( !isset( $fp['align'] ) ) {
-                       $fp['align'] = '';
+               $page = isset( $handlerParams['page'] ) ? $handlerParams['page'] : false;
+               if ( !isset( $frameParams['align'] ) ) {
+                       $frameParams['align'] = '';
                }
-               if ( !isset( $fp['alt'] ) ) {
-                       $fp['alt'] = '';
+               if ( !isset( $frameParams['alt'] ) ) {
+                       $frameParams['alt'] = '';
                }
-               if ( !isset( $fp['title'] ) ) {
-                       $fp['title'] = '';
+               if ( !isset( $frameParams['title'] ) ) {
+                       $frameParams['title'] = '';
                }
-               if ( !isset( $fp['class'] ) ) {
-                       $fp['class'] = '';
+               if ( !isset( $frameParams['class'] ) ) {
+                       $frameParams['class'] = '';
                }
 
                $prefix = $postfix = '';
 
-               if ( 'center' == $fp['align'] ) {
+               if ( 'center' == $frameParams['align'] ) {
                        $prefix = '<div class="center">';
                        $postfix = '</div>';
-                       $fp['align'] = 'none';
+                       $frameParams['align'] = 'none';
                }
-               if ( $file && !isset( $hp['width'] ) ) {
-                       if ( isset( $hp['height'] ) && $file->isVectorized() ) {
+               if ( $file && !isset( $handlerParams['width'] ) ) {
+                       if ( isset( $handlerParams['height'] ) && $file->isVectorized() ) {
                                // If its a vector image, and user only specifies height
                                // we don't want it to be limited by its "normal" width.
                                global $wgSVGMaxSize;
-                               $hp['width'] = $wgSVGMaxSize;
+                               $handlerParams['width'] = $wgSVGMaxSize;
                        } else {
-                               $hp['width'] = $file->getWidth( $page );
+                               $handlerParams['width'] = $file->getWidth( $page );
                        }
 
-                       if ( isset( $fp['thumbnail'] )
-                               || isset( $fp['manualthumb'] )
-                               || isset( $fp['framed'] )
-                               || isset( $fp['frameless'] )
-                               || !$hp['width']
+                       if ( isset( $frameParams['thumbnail'] )
+                               || isset( $frameParams['manualthumb'] )
+                               || isset( $frameParams['framed'] )
+                               || isset( $frameParams['frameless'] )
+                               || !$handlerParams['width']
                        ) {
                                global $wgThumbLimits, $wgThumbUpright;
 
@@ -477,73 +473,77 @@ class Linker {
                                }
 
                                // Reduce width for upright images when parameter 'upright' is used
-                               if ( isset( $fp['upright'] ) && $fp['upright'] == 0 ) {
-                                       $fp['upright'] = $wgThumbUpright;
+                               if ( isset( $frameParams['upright'] ) && $frameParams['upright'] == 0 ) {
+                                       $frameParams['upright'] = $wgThumbUpright;
                                }
 
                                // For caching health: If width scaled down due to upright
                                // parameter, round to full __0 pixel to avoid the creation of a
                                // lot of odd thumbs.
-                               $prefWidth = isset( $fp['upright'] ) ?
-                                       round( $wgThumbLimits[$widthOption] * $fp['upright'], -1 ) :
+                               $prefWidth = isset( $frameParams['upright'] ) ?
+                                       round( $wgThumbLimits[$widthOption] * $frameParams['upright'], -1 ) :
                                        $wgThumbLimits[$widthOption];
 
                                // Use width which is smaller: real image width or user preference width
                                // Unless image is scalable vector.
-                               if ( !isset( $hp['height'] ) && ( $hp['width'] <= 0 ||
-                                               $prefWidth < $hp['width'] || $file->isVectorized() ) ) {
-                                       $hp['width'] = $prefWidth;
+                               if ( !isset( $handlerParams['height'] ) && ( $handlerParams['width'] <= 0 ||
+                                               $prefWidth < $handlerParams['width'] || $file->isVectorized() ) ) {
+                                       $handlerParams['width'] = $prefWidth;
                                }
                        }
                }
 
-               if ( isset( $fp['thumbnail'] ) || isset( $fp['manualthumb'] ) || isset( $fp['framed'] ) ) {
+               if ( isset( $frameParams['thumbnail'] ) || isset( $frameParams['manualthumb'] )
+                       || isset( $frameParams['framed'] )
+               ) {
                        # Create a thumbnail. Alignment depends on the writing direction of
                        # the page content language (right-aligned for LTR languages,
                        # left-aligned for RTL languages)
                        # If a thumbnail width has not been provided, it is set
                        # to the default user option as specified in Language*.php
-                       if ( $fp['align'] == '' ) {
-                               $fp['align'] = $parser->getTargetLanguage()->alignEnd();
+                       if ( $frameParams['align'] == '' ) {
+                               $frameParams['align'] = $parser->getTargetLanguage()->alignEnd();
                        }
-                       return $prefix . self::makeThumbLink2( $title, $file, $fp, $hp, $time, $query ) . $postfix;
+                       return $prefix .
+                               self::makeThumbLink2( $title, $file, $frameParams, $handlerParams, $time, $query ) .
+                               $postfix;
                }
 
-               if ( $file && isset( $fp['frameless'] ) ) {
+               if ( $file && isset( $frameParams['frameless'] ) ) {
                        $srcWidth = $file->getWidth( $page );
                        # For "frameless" option: do not present an image bigger than the
                        # source (for bitmap-style images). This is the same behavior as the
                        # "thumb" option does it already.
-                       if ( $srcWidth && !$file->mustRender() && $hp['width'] > $srcWidth ) {
-                               $hp['width'] = $srcWidth;
+                       if ( $srcWidth && !$file->mustRender() && $handlerParams['width'] > $srcWidth ) {
+                               $handlerParams['width'] = $srcWidth;
                        }
                }
 
-               if ( $file && isset( $hp['width'] ) ) {
+               if ( $file && isset( $handlerParams['width'] ) ) {
                        # Create a resized image, without the additional thumbnail features
-                       $thumb = $file->transform( $hp );
+                       $thumb = $file->transform( $handlerParams );
                } else {
                        $thumb = false;
                }
 
                if ( !$thumb ) {
-                       $s = self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
+                       $s = self::makeBrokenImageLinkObj( $title, $frameParams['title'], '', '', '', $time == true );
                } else {
-                       self::processResponsiveImages( $file, $thumb, $hp );
+                       self::processResponsiveImages( $file, $thumb, $handlerParams );
                        $params = [
-                               'alt' => $fp['alt'],
-                               'title' => $fp['title'],
-                               'valign' => isset( $fp['valign'] ) ? $fp['valign'] : false,
-                               'img-class' => $fp['class'] ];
-                       if ( isset( $fp['border'] ) ) {
+                               'alt' => $frameParams['alt'],
+                               'title' => $frameParams['title'],
+                               'valign' => isset( $frameParams['valign'] ) ? $frameParams['valign'] : false,
+                               'img-class' => $frameParams['class'] ];
+                       if ( isset( $frameParams['border'] ) ) {
                                $params['img-class'] .= ( $params['img-class'] !== '' ? ' ' : '' ) . 'thumbborder';
                        }
-                       $params = self::getImageLinkMTOParams( $fp, $query, $parser ) + $params;
+                       $params = self::getImageLinkMTOParams( $frameParams, $query, $parser ) + $params;
 
                        $s = $thumb->toHtml( $params );
                }
-               if ( $fp['align'] != '' ) {
-                       $s = "<div class=\"float{$fp['align']}\">{$s}</div>";
+               if ( $frameParams['align'] != '' ) {
+                       $s = "<div class=\"float{$frameParams['align']}\">{$s}</div>";
                }
                return str_replace( "\n", ' ', $prefix . $s . $postfix );
        }
@@ -571,7 +571,9 @@ class Linker {
                                }
                        }
                } elseif ( isset( $frameParams['link-title'] ) && $frameParams['link-title'] !== '' ) {
-                       $mtoParams['custom-title-link'] = self::normaliseSpecialPage( $frameParams['link-title'] );
+                       $mtoParams['custom-title-link'] = Title::newFromLinkTarget(
+                               self::normaliseSpecialPage( $frameParams['link-title'] )
+                       );
                } elseif ( !empty( $frameParams['no-link'] ) ) {
                        // No link
                } else {
@@ -624,65 +626,61 @@ class Linker {
        ) {
                $exists = $file && $file->exists();
 
-               # Shortcuts
-               $fp =& $frameParams;
-               $hp =& $handlerParams;
-
-               $page = isset( $hp['page'] ) ? $hp['page'] : false;
-               if ( !isset( $fp['align'] ) ) {
-                       $fp['align'] = 'right';
+               $page = isset( $handlerParams['page'] ) ? $handlerParams['page'] : false;
+               if ( !isset( $frameParams['align'] ) ) {
+                       $frameParams['align'] = 'right';
                }
-               if ( !isset( $fp['alt'] ) ) {
-                       $fp['alt'] = '';
+               if ( !isset( $frameParams['alt'] ) ) {
+                       $frameParams['alt'] = '';
                }
-               if ( !isset( $fp['title'] ) ) {
-                       $fp['title'] = '';
+               if ( !isset( $frameParams['title'] ) ) {
+                       $frameParams['title'] = '';
                }
-               if ( !isset( $fp['caption'] ) ) {
-                       $fp['caption'] = '';
+               if ( !isset( $frameParams['caption'] ) ) {
+                       $frameParams['caption'] = '';
                }
 
-               if ( empty( $hp['width'] ) ) {
+               if ( empty( $handlerParams['width'] ) ) {
                        // Reduce width for upright images when parameter 'upright' is used
-                       $hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
+                       $handlerParams['width'] = isset( $frameParams['upright'] ) ? 130 : 180;
                }
                $thumb = false;
                $noscale = false;
                $manualthumb = false;
 
                if ( !$exists ) {
-                       $outerWidth = $hp['width'] + 2;
+                       $outerWidth = $handlerParams['width'] + 2;
                } else {
-                       if ( isset( $fp['manualthumb'] ) ) {
+                       if ( isset( $frameParams['manualthumb'] ) ) {
                                # Use manually specified thumbnail
-                               $manual_title = Title::makeTitleSafe( NS_FILE, $fp['manualthumb'] );
+                               $manual_title = Title::makeTitleSafe( NS_FILE, $frameParams['manualthumb'] );
                                if ( $manual_title ) {
                                        $manual_img = wfFindFile( $manual_title );
                                        if ( $manual_img ) {
-                                               $thumb = $manual_img->getUnscaledThumb( $hp );
+                                               $thumb = $manual_img->getUnscaledThumb( $handlerParams );
                                                $manualthumb = true;
                                        } else {
                                                $exists = false;
                                        }
                                }
-                       } elseif ( isset( $fp['framed'] ) ) {
+                       } elseif ( isset( $frameParams['framed'] ) ) {
                                // Use image dimensions, don't scale
-                               $thumb = $file->getUnscaledThumb( $hp );
+                               $thumb = $file->getUnscaledThumb( $handlerParams );
                                $noscale = true;
                        } else {
                                # Do not present an image bigger than the source, for bitmap-style images
                                # This is a hack to maintain compatibility with arbitrary pre-1.10 behavior
                                $srcWidth = $file->getWidth( $page );
-                               if ( $srcWidth && !$file->mustRender() && $hp['width'] > $srcWidth ) {
-                                       $hp['width'] = $srcWidth;
+                               if ( $srcWidth && !$file->mustRender() && $handlerParams['width'] > $srcWidth ) {
+                                       $handlerParams['width'] = $srcWidth;
                                }
-                               $thumb = $file->transform( $hp );
+                               $thumb = $file->transform( $handlerParams );
                        }
 
                        if ( $thumb ) {
                                $outerWidth = $thumb->getWidth() + 2;
                        } else {
-                               $outerWidth = $hp['width'] + 2;
+                               $outerWidth = $handlerParams['width'] + 2;
                        }
                }
 
@@ -694,35 +692,35 @@ class Linker {
                        $url = wfAppendQuery( $url, [ 'page' => $page ] );
                }
                if ( $manualthumb
-                       && !isset( $fp['link-title'] )
-                       && !isset( $fp['link-url'] )
-                       && !isset( $fp['no-link'] ) ) {
-                       $fp['link-url'] = $url;
+                       && !isset( $frameParams['link-title'] )
+                       && !isset( $frameParams['link-url'] )
+                       && !isset( $frameParams['no-link'] ) ) {
+                       $frameParams['link-url'] = $url;
                }
 
-               $s = "<div class=\"thumb t{$fp['align']}\">"
+               $s = "<div class=\"thumb t{$frameParams['align']}\">"
                        . "<div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">";
 
                if ( !$exists ) {
-                       $s .= self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
+                       $s .= self::makeBrokenImageLinkObj( $title, $frameParams['title'], '', '', '', $time == true );
                        $zoomIcon = '';
                } elseif ( !$thumb ) {
                        $s .= wfMessage( 'thumbnail_error', '' )->escaped();
                        $zoomIcon = '';
                } else {
                        if ( !$noscale && !$manualthumb ) {
-                               self::processResponsiveImages( $file, $thumb, $hp );
+                               self::processResponsiveImages( $file, $thumb, $handlerParams );
                        }
                        $params = [
-                               'alt' => $fp['alt'],
-                               'title' => $fp['title'],
-                               'img-class' => ( isset( $fp['class'] ) && $fp['class'] !== ''
-                                       ? $fp['class'] . ' '
+                               'alt' => $frameParams['alt'],
+                               'title' => $frameParams['title'],
+                               'img-class' => ( isset( $frameParams['class'] ) && $frameParams['class'] !== ''
+                                       ? $frameParams['class'] . ' '
                                        : '' ) . 'thumbimage'
                        ];
-                       $params = self::getImageLinkMTOParams( $fp, $query ) + $params;
+                       $params = self::getImageLinkMTOParams( $frameParams, $query ) + $params;
                        $s .= $thumb->toHtml( $params );
-                       if ( isset( $fp['framed'] ) ) {
+                       if ( isset( $frameParams['framed'] ) ) {
                                $zoomIcon = "";
                        } else {
                                $zoomIcon = Html::rawElement( 'div', [ 'class' => 'magnify' ],
@@ -733,7 +731,7 @@ class Linker {
                                                "" ) );
                        }
                }
-               $s .= '  <div class="thumbcaption">' . $zoomIcon . $fp['caption'] . "</div></div></div>";
+               $s .= '  <div class="thumbcaption">' . $zoomIcon . $frameParams['caption'] . "</div></div></div>";
                return str_replace( "\n", ' ', $s );
        }
 
index 2a00900..cded064 100644 (file)
@@ -286,16 +286,6 @@ class MediaWiki {
                                // may still be a wikipage redirect to another article or URL.
                                $article = $this->initializeArticle();
                                if ( is_object( $article ) ) {
-                                       $url = $request->getFullRequestURL(); // requested URL
-                                       if (
-                                               $request->getMethod() === 'GET' &&
-                                               $url === $article->getTitle()->getCanonicalURL() &&
-                                               $article->checkTouched() &&
-                                               $output->checkLastModified( $article->getTouched() )
-                                       ) {
-                                               wfDebug( __METHOD__ . ": done 304\n" );
-                                               return;
-                                       }
                                        $this->performAction( $article, $requestTitle );
                                } elseif ( is_string( $article ) ) {
                                        $output->redirect( $article );
@@ -571,13 +561,14 @@ class MediaWiki {
                        // Abort if any transaction was too big
                        [ 'maxWriteDuration' => $config->get( 'MaxUserDBWriteDuration' ) ]
                );
-               // Record ChronologyProtector positions
-               $factory->shutdown();
-               wfDebug( __METHOD__ . ': all transactions committed' );
 
                DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND );
                wfDebug( __METHOD__ . ': pre-send deferred updates completed' );
 
+               // Record ChronologyProtector positions
+               $factory->shutdown();
+               wfDebug( __METHOD__ . ': all transactions committed' );
+
                // Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this
                // POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so
                // ChronologyProtector works for cacheable URLs.
index 49891df..037e96f 100644 (file)
@@ -198,7 +198,14 @@ class MediaWikiServices extends ServiceContainer {
         */
        private function salvage( self $other ) {
                foreach ( $this->getServiceNames() as $name ) {
-                       $oldService = $other->peekService( $name );
+                       // The service could be new in the new instance and not registered in the
+                       // other instance (e.g. an extension that was loaded after the instantiation of
+                       // the other instance. Skip this service in this case. See T143974
+                       try {
+                               $oldService = $other->peekService( $name );
+                       } catch ( NoSuchServiceException $e ) {
+                               continue;
+                       }
 
                        if ( $oldService instanceof SalvageableService ) {
                                /** @var SalvageableService $newService */
index 2c979de..c2c954a 100644 (file)
  *
  * @code
  *     // old style:
- *     wfMsgExt( 'key', array( 'parseinline' ), 'apple' );
+ *     wfMsgExt( 'key', [ 'parseinline' ], 'apple' );
  *     // new style:
  *     wfMessage( 'key', 'apple' )->parse();
  * @endcode
  * Places where HTML cannot be used. {{-transformation is done.
  * @code
  *     // old style:
- *     wfMsgExt( 'key', array( 'parsemag' ), 'apple', 'pear' );
+ *     wfMsgExt( 'key', [ 'parsemag' ], 'apple', 'pear' );
  *     // new style:
  *     wfMessage( 'key', 'apple', 'pear' )->text();
  * @endcode
index c7499b1..1083687 100644 (file)
@@ -2547,6 +2547,7 @@ class OutputPage extends ContextSource {
        public function showLagWarning( $lag ) {
                $config = $this->getConfig();
                if ( $lag >= $config->get( 'SlaveLagWarning' ) ) {
+                       $lag = floor( $lag ); // floor to avoid nano seconds to display
                        $message = $lag < $config->get( 'SlaveLagCritical' )
                                ? 'lag-warn-normal'
                                : 'lag-warn-high';
@@ -2688,12 +2689,6 @@ class OutputPage extends ContextSource {
                                                        // Special case in buildExemptModules()
                                                        return false;
                                                }
-                                               if ( $name === 'site.styles' ) {
-                                                       // HACK: Technically, 'site.styles' isn't in a separate request group.
-                                                       // But, in order to ensure its styles are in the right position,
-                                                       // pretend it's in a group called 'site'.
-                                                       $group = 'site';
-                                               }
                                                if ( isset( $exemptGroups[$group] ) ) {
                                                        $exemptStates[$name] = 'ready';
                                                        if ( !$module->isKnownEmpty( $context ) ) {
index 70addfc..5a9f0b0 100644 (file)
@@ -1494,7 +1494,7 @@ class Preferences {
 
                        $context = $form->getContext();
                        // Set session data for the success message
-                       $context->getRequest()->setSessionData( 'specialPreferencesSaveSuccess', 1 );
+                       $context->getRequest()->getSession()->set( 'specialPreferencesSaveSuccess', 1 );
 
                        $context->getOutput()->redirect( $url );
                }
index 553e597..5492737 100644 (file)
@@ -394,6 +394,32 @@ class WebRequest {
                }
        }
 
+       /**
+        * Fetch a scalar from the input without normalization, or return $default
+        * if it's not set.
+        *
+        * Unlike self::getVal(), this does not perform any normalization on the
+        * input value.
+        *
+        * @since 1.28
+        * @param string $name
+        * @param string|null $default Optional default
+        * @return string
+        */
+       public function getRawVal( $name, $default = null ) {
+               $name = strtr( $name, '.', '_' ); // See comment in self::getGPCVal()
+               if ( isset( $this->data[$name] ) && !is_array( $this->data[$name] ) ) {
+                       $val = $this->data[$name];
+               } else {
+                       $val = $default;
+               }
+               if ( is_null( $val ) ) {
+                       return $val;
+               } else {
+                       return (string)$val;
+               }
+       }
+
        /**
         * Fetch a scalar from the input or return $default if it's not set.
         * Returns a string. Arrays are discarded. Useful for
index 3e760fd..3dc611b 100644 (file)
@@ -57,6 +57,9 @@ class RollbackAction extends FormlessAction {
                if ( $from === null || $from === '' ) {
                        throw new ErrorPageError( 'rollbackfailed', 'rollback-missingparam' );
                }
+               if ( !$rev ) {
+                       throw new ErrorPageError( 'rollbackfailed', 'rollback-missingrevision' );
+               }
                if ( $from !== $rev->getUserText() ) {
                        throw new ErrorPageError( 'rollbackfailed', 'alreadyrolled', [
                                $this->getTitle()->getPrefixedText(),
index 3a24565..55507f5 100644 (file)
@@ -41,6 +41,30 @@ class ViewAction extends FormlessAction {
        }
 
        public function show() {
+               $config = $this->context->getConfig();
+
+               if (
+                       $config->get( 'DebugToolbar' ) == false && // don't let this get stuck on pages
+                       $this->page->checkTouched() // page exists and is not a redirect
+               ) {
+                       // Include any redirect in the last-modified calculation
+                       $redirFromTitle = $this->page->getRedirectedFrom();
+                       if ( !$redirFromTitle ) {
+                               $touched = $this->page->getTouched();
+                       } elseif ( $config->get( 'MaxRedirects' ) <= 1 ) {
+                               $touched = max( $this->page->getTouched(), $redirFromTitle->getTouched() );
+                       } else {
+                               // Don't bother following the chain and getting the max mtime
+                               $touched = null;
+                       }
+
+                       // Send HTTP 304 if the IMS matches or otherwise set expiry/last-modified headers
+                       if ( $touched && $this->getOutput()->checkLastModified( $touched ) ) {
+                               wfDebug( __METHOD__ . ": done 304\n" );
+                               return;
+                       }
+               }
+
                $this->page->view();
        }
 }
index a4f54ee..8e57f93 100644 (file)
@@ -85,6 +85,7 @@ class ApiAuthManagerHelper {
                                        'key' => $message->getKey(),
                                        'params' => $message->getParams(),
                                ];
+                               ApiResult::setIndexedTagName( $res[$key]['params'], 'param' );
                                break;
                }
        }
index 66c1b53..55d2430 100644 (file)
@@ -1000,6 +1000,31 @@ abstract class ApiBase extends ContextSource {
                                        $type = $this->getModuleManager()->getNames( $paramName );
                                }
                        }
+
+                       $request = $this->getMain()->getRequest();
+                       $rawValue = $request->getRawVal( $encParamName );
+                       if ( $rawValue === null ) {
+                               $rawValue = $default;
+                       }
+
+                       // Preserve U+001F for self::parseMultiValue(), or error out if that won't be called
+                       if ( isset( $value ) && substr( $rawValue, 0, 1 ) === "\x1f" ) {
+                               if ( $multi ) {
+                                       // This loses the potential $wgContLang->checkTitleEncoding() transformation
+                                       // done by WebRequest for $_GET. Let's call that a feature.
+                                       $value = join( "\x1f", $request->normalizeUnicode( explode( "\x1f", $rawValue ) ) );
+                               } else {
+                                       $this->dieUsage(
+                                               "U+001F multi-value separation may only be used for multi-valued parameters.",
+                                               'badvalue_notmultivalue'
+                                       );
+                               }
+                       }
+
+                       // Check for NFC normalization, and warn
+                       if ( $rawValue !== $value ) {
+                               $this->handleParamNormalization( $paramName, $value, $rawValue );
+                       }
                }
 
                if ( isset( $value ) && ( $multi || is_array( $type ) ) ) {
@@ -1145,6 +1170,40 @@ abstract class ApiBase extends ContextSource {
                return $value;
        }
 
+       /**
+        * Handle when a parameter was Unicode-normalized
+        * @since 1.28
+        * @param string $paramName Unprefixed parameter name
+        * @param string $value Input that will be used.
+        * @param string $rawValue Input before normalization.
+        */
+       protected function handleParamNormalization( $paramName, $value, $rawValue ) {
+               $encParamName = $this->encodeParamName( $paramName );
+               $this->setWarning(
+                       "The value passed for '$encParamName' contains invalid or non-normalized data. "
+                       . 'Textual data should be valid, NFC-normalized Unicode without '
+                       . 'C0 control characters other than HT (\\t), LF (\\n), and CR (\\r).'
+               );
+       }
+
+       /**
+        * Split a multi-valued parameter string, like explode()
+        * @since 1.28
+        * @param string $value
+        * @param int $limit
+        * @return string[]
+        */
+       protected function explodeMultiValue( $value, $limit ) {
+               if ( substr( $value, 0, 1 ) === "\x1f" ) {
+                       $sep = "\x1f";
+                       $value = substr( $value, 1 );
+               } else {
+                       $sep = '|';
+               }
+
+               return explode( $sep, $value, $limit );
+       }
+
        /**
         * Return an array of values that were given in a 'a|b|c' notation,
         * after it optionally validates them against the list allowed values.
@@ -1159,13 +1218,13 @@ abstract class ApiBase extends ContextSource {
         * @return string|string[] (allowMultiple ? an_array_of_values : a_single_value)
         */
        protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues ) {
-               if ( trim( $value ) === '' && $allowMultiple ) {
+               if ( ( trim( $value ) === '' || trim( $value ) === "\x1f" ) && $allowMultiple ) {
                        return [];
                }
 
                // This is a bit awkward, but we want to avoid calling canApiHighLimits()
                // because it unstubs $wgUser
-               $valuesList = explode( '|', $value, self::LIMIT_SML2 + 1 );
+               $valuesList = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
                $sizeLimit = count( $valuesList ) > self::LIMIT_SML1 && $this->mMainModule->canApiHighLimits()
                        ? self::LIMIT_SML2
                        : self::LIMIT_SML1;
index 5271996..407ae71 100644 (file)
@@ -87,6 +87,7 @@ class ApiCSPReport extends ApiBase {
                $reportOnly = $this->getParameter( 'reportonly' );
                $userAgent = $this->getRequest()->getHeader( 'user-agent' );
                $source = $this->getParameter( 'source' );
+               $falsePositives = $this->getConfig()->get( 'CSPFalsePositiveUrls' );
 
                $flags = [];
                if ( $source !== 'internal' ) {
@@ -95,6 +96,16 @@ class ApiCSPReport extends ApiBase {
                if ( $reportOnly ) {
                        $flags[] = 'report-only';
                }
+
+               if (
+                       ( isset( $report['blocked-uri'] ) &&
+                       isset( $falsePositives[$report['blocked-uri']] ) )
+                       || ( isset( $report['source-file'] ) &&
+                       isset( $falsePositives[$report['source-file']] ) )
+               ) {
+                       // Report caused by Ad-Ware
+                       $flags[] = 'false-positive';
+               }
                return $flags;
        }
 
index c19926a..6d9184f 100644 (file)
@@ -202,7 +202,7 @@ class ApiErrorFormatter {
 
                        case 'raw':
                                $value += [
-                                       'message' => $msg->getKey(),
+                                       'key' => $msg->getKey(),
                                        'params' => $msg->getParams(),
                                ];
                                ApiResult::setIndexedTagName( $value['params'], 'param' );
index 90438d4..ed229cb 100644 (file)
@@ -495,10 +495,14 @@ class ApiPageSet extends ApiBase {
         * @since 1.21
         */
        public function getNormalizedTitlesAsResult( $result = null ) {
+               global $wgContLang;
+
                $values = [];
                foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
+                       $encode = ( $wgContLang->normalize( $rawTitleStr ) !== $rawTitleStr );
                        $values[] = [
-                               'from' => $rawTitleStr,
+                               'fromencoded' => $encode,
+                               'from' => $encode ? rawurlencode( $rawTitleStr ) : $rawTitleStr,
                                'to' => $titleStr
                        ];
                }
@@ -1403,6 +1407,23 @@ class ApiPageSet extends ApiBase {
                return $result;
        }
 
+       protected function handleParamNormalization( $paramName, $value, $rawValue ) {
+               parent::handleParamNormalization( $paramName, $value, $rawValue );
+
+               if ( $paramName === 'titles' ) {
+                       // For the 'titles' parameter, we want to split it like ApiBase would
+                       // and add any changed titles to $this->mNormalizedTitles
+                       $value = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
+                       $l = count( $value );
+                       $rawValue = $this->explodeMultiValue( $rawValue, $l );
+                       for ( $i = 0; $i < $l; $i++ ) {
+                               if ( $value[$i] !== $rawValue[$i] ) {
+                                       $this->mNormalizedTitles[$rawValue[$i]] = $value[$i];
+                               }
+                       }
+               }
+       }
+
        private static $generators = null;
 
        /**
index c3c9e21..25e1a7f 100644 (file)
@@ -162,6 +162,7 @@ class ApiParamInfo extends ApiBase {
                                                'key' => $m->getKey(),
                                                'params' => $m->getParams(),
                                        ];
+                                       ApiResult::setIndexedTagName( $a['params'], 'param' );
                                        if ( $m instanceof ApiHelpParamValueMessage ) {
                                                $a['forvalue'] = $m->getParamValue();
                                        }
index 8b8bd01..5d7c664 100644 (file)
@@ -173,10 +173,8 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $this->addWhereFld( 'ipb_deleted', 0 );
                }
 
-               // Purge expired entries on one in every 10 queries
-               if ( !mt_rand( 0, 10 ) ) {
-                       Block::purgeExpired();
-               }
+               # Filter out expired rows
+               $this->addWhere( 'ipb_expiry > ' . $db->addQuotes( $db->timestamp() ) );
 
                $res = $this->select( __METHOD__ );
 
index 00846f5..e308ba4 100644 (file)
@@ -415,7 +415,7 @@ class ApiResult implements ApiSerializable {
                        if ( $this->maxSize !== false && $newsize > $this->maxSize ) {
                                /// @todo Add i18n message when replacing calls to ->setWarning()
                                $msg = new ApiRawMessage( 'This result was truncated because it would otherwise ' .
-                                       ' be larger than the limit of $1 bytes', 'truncatedresult' );
+                                       'be larger than the limit of $1 bytes', 'truncatedresult' );
                                $msg->numParams( $this->maxSize );
                                $this->errorFormatter->addWarning( 'result', $msg );
                                return false;
index f7ce552..54d3c3c 100644 (file)
@@ -109,16 +109,19 @@ class ApiUpload extends ApiBase {
                // Get the result based on the current upload context:
                try {
                        $result = $this->getContextResult();
-                       if ( $result['result'] === 'Success' ) {
-                               $result['imageinfo'] = $this->mUpload->getImageInfo( $this->getResult() );
-                       }
                } catch ( UploadStashException $e ) { // XXX: don't spam exception log
                        list( $msg, $code ) = $this->handleStashException( get_class( $e ), $e->getMessage() );
                        $this->dieUsage( $msg, $code );
                }
-
                $this->getResult()->addValue( null, $this->getModuleName(), $result );
 
+               // Add 'imageinfo' in a separate addValue() call. File metadata can be unreasonably large,
+               // so otherwise when it exceeded $wgAPIMaxResultSize, no result would be returned (T143993).
+               if ( $result['result'] === 'Success' ) {
+                       $imageinfo = $this->mUpload->getImageInfo( $this->getResult() );
+                       $this->getResult()->addValue( $this->getModuleName(), 'imageinfo', $imageinfo );
+               }
+
                // Cleanup any temporary mess
                $this->mUpload->cleanupTempFile();
        }
@@ -445,7 +448,18 @@ class ApiUpload extends ApiBase {
                                }
                        }
                        unset( $progress['status'] ); // remove Status object
+                       $imageinfo = null;
+                       if ( isset( $progress['imageinfo'] ) ) {
+                               $imageinfo = $progress['imageinfo'];
+                               unset( $progress['imageinfo'] );
+                       }
+
                        $this->getResult()->addValue( null, $this->getModuleName(), $progress );
+                       // Add 'imageinfo' in a separate addValue() call. File metadata can be unreasonably large,
+                       // so otherwise when it exceeded $wgAPIMaxResultSize, no result would be returned (T143993).
+                       if ( $imageinfo ) {
+                               $this->getResult()->addValue( $this->getModuleName(), 'imageinfo', $imageinfo );
+                       }
 
                        return false;
                }
index 1815836..a68a87f 100644 (file)
        "api-help-param-deprecated": "Deprecated.",
        "api-help-param-required": "This parameter is required.",
        "api-help-datatypes-header": "Data types",
-       "api-help-datatypes": "Some parameter types in API requests need further explanation:\n;boolean\n:Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely.\n;timestamp\n:Timestamps may be specified in several formats. ISO 8601 date and time is recommended. All times are in UTC, any included timezone is ignored.\n:* ISO 8601 date and time, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (punctuation and <kbd>Z</kbd> are optional)\n:* ISO 8601 date and time with (ignored) fractional seconds, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (dashes, colons, and <kbd>Z</kbd> are optional)\n:* MediaWiki format, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Generic numeric format, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (optional timezone of <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> is ignored)\n:* EXIF format, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*RFC 2822 format (timezone may be omitted), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 format (timezone may be omitted), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Seconds since 1970-01-01T00:00:00Z as a 1 to 13 digit integer (excluding <kbd>0</kbd>)\n:* The string <kbd>now</kbd>",
+       "api-help-datatypes": "Input to MediaWiki should be NFC-normalized UTF-8. MediaWiki may attempt to convert other input, but this may cause some operations (such as [[Special:ApiHelp/edit|edits]] with MD5 checks) to fail.\n\nSome parameter types in API requests need further explanation:\n;boolean\n:Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely.\n;timestamp\n:Timestamps may be specified in several formats. ISO 8601 date and time is recommended. All times are in UTC, any included timezone is ignored.\n:* ISO 8601 date and time, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (punctuation and <kbd>Z</kbd> are optional)\n:* ISO 8601 date and time with (ignored) fractional seconds, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (dashes, colons, and <kbd>Z</kbd> are optional)\n:* MediaWiki format, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Generic numeric format, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (optional timezone of <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> is ignored)\n:* EXIF format, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*RFC 2822 format (timezone may be omitted), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 format (timezone may be omitted), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Seconds since 1970-01-01T00:00:00Z as a 1 to 13 digit integer (excluding <kbd>0</kbd>)\n:* The string <kbd>now</kbd>\n;alternative multiple-value separator\n:Parameters that take multiple values are normally submitted with the values separated using the pipe character, e.g. <kbd>param=value1|value2</kbd> or <kbd>param=value1%7Cvalue2</kbd>. If a value must contain the pipe character, use U+001F (Unit Separator) as the separator ''and'' prefix the value with U+001F, e.g. <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
        "api-help-param-type-limit": "Type: integer or <kbd>max</kbd>",
        "api-help-param-type-integer": "Type: {{PLURAL:$1|1=integer|2=list of integers}}",
        "api-help-param-type-boolean": "Type: boolean ([[Special:ApiHelp/main#main/datatypes|details]])",
        "api-help-param-type-password": "",
        "api-help-param-type-timestamp": "Type: {{PLURAL:$1|1=timestamp|2=list of timestamps}} ([[Special:ApiHelp/main#main/datatypes|allowed formats]])",
        "api-help-param-type-user": "Type: {{PLURAL:$1|1=user name|2=list of user names}}",
-       "api-help-param-list": "{{PLURAL:$1|1=One of the following values|2=Values (separate with <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=One of the following values|2=Values (separate with <kbd>{{!}}</kbd> or [[Special:ApiHelp/main#main/datatypes|alternative]])}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Must be empty|Can be empty, or $2}}",
        "api-help-param-limit": "No more than $1 allowed.",
        "api-help-param-limit2": "No more than $1 ($2 for bots) allowed.",
        "api-help-param-integer-max": "The {{PLURAL:$1|1=value|2=values}} must be no greater than $3.",
        "api-help-param-integer-minmax": "The {{PLURAL:$1|1=value|2=values}} must be between $2 and $3.",
        "api-help-param-upload": "Must be posted as a file upload using multipart/form-data.",
-       "api-help-param-multi-separate": "Separate values with <kbd>|</kbd>.",
+       "api-help-param-multi-separate": "Separate values with <kbd>|</kbd> or [[Special:ApiHelp/main#main/datatypes|alternative]].",
        "api-help-param-multi-max": "Maximum number of values is {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} for bots).",
        "api-help-param-default": "Default: $1",
        "api-help-param-default-empty": "Default: <span class=\"apihelp-empty\">(empty)</span>",
index b8756c5..059a7c5 100644 (file)
        "apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
        "apihelp-query+alllinks-example-generator": "Obtiene páginas que contienen los enlaces.",
        "apihelp-query+allmessages-description": "Devolver los mensajes de este sitio.",
-       "apihelp-query+allmessages-param-messages": "Qué mensajes mostrar. <kbd>*</kbd> (por defecto) significa todos los mensajes.",
+       "apihelp-query+allmessages-param-messages": "Qué mensajes mostrar. <kbd>*</kbd> (predeterminado) significa todos los mensajes.",
        "apihelp-query+allmessages-param-prop": "Qué propiedades se obtendrán.",
        "apihelp-query+allmessages-param-enableparser": "Establecer para habilitar el analizador, se preprocesará el wikitexto del mensaje (sustitución de palabras mágicas, uso de plantillas, etc.).",
        "apihelp-query+allmessages-param-nocontent": "Si se establece, no incluya el contenido de los mensajes en la salida.",
        "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Añade el comentario analizado para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-flags": "Añade marcas para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Añade la marca de tiempo de la edición.",
-       "apihelp-query+recentchanges-paramvalue-prop-title": "Añade el título de la página de la edición.",
+       "apihelp-query+recentchanges-paramvalue-prop-title": "Añade el título de página de la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-ids": "Añade los códigos ID de la página, de los cambios recientes y de las revisiones antigua y nueva.",
        "apihelp-query+recentchanges-paramvalue-prop-sizes": "Añade la longitud antigua y la longitud nueva de la página en bytes.",
        "apihelp-query+recentchanges-paramvalue-prop-redirect": "Etiqueta la edición si la página es una redirección.",
        "apihelp-query+redirects-param-namespace": "Incluir solo páginas de estos espacios de nombres.",
        "apihelp-query+redirects-param-limit": "Cuántas redirecciones se devolverán.",
        "apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
-       "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]]",
+       "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]].",
        "apihelp-query+revisions-param-end": "Enumerar hasta esta marca de tiempo.",
        "apihelp-query+revisions-param-user": "Incluir solo las revisiones realizadas por el usuario.",
        "apihelp-query+revisions-param-excludeuser": "Excluir las revisiones realizadas por el usuario.",
index d3ef0e4..af13948 100644 (file)
@@ -36,6 +36,7 @@
        "apihelp-block-param-watchuser": "その利用者またはIPアドレスの利用者ページとトークページをウォッチします。",
        "apihelp-block-example-ip-simple": "IPアドレス <kbd>192.0.2.5</kbd> を <kbd>First strike<kbd> という理由で3日ブロックする",
        "apihelp-block-example-user-complex": "利用者 <kbd>Vandal</kbd> を <kbd>Vandalism</kbd> という理由で無期限ブロックし、新たなアカウント作成とメールの送信を禁止する。",
+       "apihelp-changeauthenticationdata-example-password": "現在の利用者のパスワードを <kbd>ExamplePassword</kbd> に変更する。",
        "apihelp-checktoken-description": "<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> のトークンの妥当性を確認します。",
        "apihelp-checktoken-param-type": "調べるトークンの種類。",
        "apihelp-checktoken-param-token": "調べるトークン。",
index d88e0ec..03cb2b5 100644 (file)
@@ -99,5 +99,6 @@
        "apihelp-query+watchlist-paramvalue-type-categorize": "वर्ग सदस्यता बदलते.",
        "apihelp-stashedit-param-title": "पानाच्या मथळ्याचे संपादन होत आहे.",
        "apihelp-stashedit-param-sectiontitle": "नविन विभागाचा मथळा",
-       "apihelp-stashedit-param-summary": "सारांश बदला."
+       "apihelp-stashedit-param-summary": "सारांश बदला.",
+       "api-help-examples": "{{PLURAL:$1|उदाहरण|उदाहरणे}}:"
 }
index c37931a..e285130 100644 (file)
        "apihelp-expandtemplates-param-title": "Títol de la pagina.",
        "apihelp-expandtemplates-param-text": "Wikitèxte de convertir.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Lo wikitèxte desvolopat.",
+       "apihelp-feedcontributions-description": "Renvia lo fial de las contribucions d’un utilizaire.",
        "apihelp-feedcontributions-param-feedformat": "Lo format del flux.",
        "apihelp-feedcontributions-param-year": "A partir de l’annada (e mai recent) :",
        "apihelp-feedcontributions-param-month": "A partir del mes (e mai recent) :",
+       "apihelp-feedcontributions-param-tagfilter": "Filtrar las contribucions qu'an aquestas balisas.",
+       "apihelp-feedcontributions-param-deletedonly": "Afichar solament las contribucions suprimidas.",
+       "apihelp-feedcontributions-param-hideminor": "Amagar los cambiaments mendres.",
+       "apihelp-feedcontributions-param-showsizediff": "Afichar la diferéncia de talha entre las revisions.",
        "apihelp-feedrecentchanges-param-feedformat": "Lo format del flux.",
        "apihelp-feedrecentchanges-param-hideminor": "Amagar las modificacions menoras.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar per balisa.",
index ed94c1a..c338284 100644 (file)
@@ -126,8 +126,8 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                        return AuthenticationResponse::newAbstain();
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow(
+               $dbr = wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow(
                        'user',
                        [
                                'user_id', 'user_newpassword', 'user_newpass_time',
@@ -165,8 +165,8 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                        return false;
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow(
+               $dbr = wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow(
                        'user',
                        [ 'user_newpassword', 'user_newpass_time' ],
                        [ 'user_name' => $username ],
index 59c1207..874e9c4 100644 (file)
@@ -201,6 +201,8 @@ abstract class DatabaseBase implements IDatabase {
        /** @var int[] Prior mFlags values */
        private $priorFlags = [];
 
+       /** @var Profiler */
+       protected $profiler;
        /** @var TransactionProfiler */
        protected $trxProfiler;
 
@@ -320,10 +322,6 @@ abstract class DatabaseBase implements IDatabase {
         * @return TransactionProfiler
         */
        protected function getTransactionProfiler() {
-               if ( !$this->trxProfiler ) {
-                       $this->trxProfiler = new TransactionProfiler();
-               }
-
                return $this->trxProfiler;
        }
 
@@ -583,13 +581,17 @@ abstract class DatabaseBase implements IDatabase {
 
                $this->mForeign = $foreign;
 
-               if ( isset( $params['trxProfiler'] ) ) {
-                       $this->trxProfiler = $params['trxProfiler']; // override
-               }
+               $this->profiler = isset( $params['profiler'] )
+                       ? $params['profiler']
+                       : Profiler::instance(); // @TODO: remove global state
+               $this->trxProfiler = isset( $params['trxProfiler'] )
+                       ? $params['trxProfiler']
+                       : new TransactionProfiler();
 
                if ( $user ) {
                        $this->open( $server, $user, $password, $dbName );
                }
+
        }
 
        /**
@@ -939,13 +941,10 @@ abstract class DatabaseBase implements IDatabase {
                # Include query transaction state
                $queryProf .= $this->mTrxShortId ? " [TRX#{$this->mTrxShortId}]" : "";
 
-               $profiler = Profiler::instance();
-               if ( !( $profiler instanceof ProfilerStub ) ) {
-                       $queryProfSection = $profiler->scopedProfileIn( $queryProf );
-               }
-
                $startTime = microtime( true );
+               $this->profiler->profileIn( $queryProf );
                $ret = $this->doQuery( $commentedSql );
+               $this->profiler->profileOut( $queryProf );
                $queryRuntime = microtime( true ) - $startTime;
 
                unset( $queryProfSection ); // profile out (if set)
@@ -2972,13 +2971,14 @@ abstract class DatabaseBase implements IDatabase {
                if ( $this->isOpen() && ( microtime( true ) - $this->lastPing ) < self::PING_TTL ) {
                        return true;
                }
-               try {
-                       // This will reconnect if possible, or error out if not
-                       $this->query( "SELECT 1 AS ping", __METHOD__ );
-                       return true;
-               } catch ( DBError $e ) {
-                       return false;
-               }
+
+               $ignoreErrors = true;
+               $this->clearFlag( DBO_TRX, self::REMEMBER_PRIOR );
+               // This will reconnect if possible or return false if not
+               $ok = (bool)$this->query( "SELECT 1 AS ping", __METHOD__, $ignoreErrors );
+               $this->restoreFlags( self::RESTORE_PRIOR );
+
+               return $ok;
        }
 
        /**
index 4cd02b1..cfae74f 100644 (file)
@@ -470,3 +470,21 @@ class DBReadOnlyError extends DBExpectedError {
  */
 class DBTransactionError extends DBExpectedError {
 }
+
+/**
+ * Exception class for attempted DB access
+ * @ingroup Database
+ */
+class DBAccessError extends DBUnexpectedError {
+       public function __construct() {
+               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
+                       "This is not allowed, because database access has been disabled." );
+       }
+}
+
+/**
+ * Exception class for replica DB wait timeouts
+ * @ingroup Database
+ */
+class DBReplicationWaitError extends DBUnexpectedError {
+}
index 1aa931e..b689e82 100644 (file)
@@ -42,7 +42,7 @@ interface IDatabase {
 
        /** @var string Transaction is requested by regular caller outside of the DB layer */
        const TRANSACTION_EXPLICIT = '';
-       /** @var string Transaction is requested interally via DBO_TRX/startAtomic() */
+       /** @var string Transaction is requested internally via DBO_TRX/startAtomic() */
        const TRANSACTION_INTERNAL = 'implicit';
 
        /** @var string Transaction operation comes from service managing all DBs */
@@ -50,7 +50,7 @@ interface IDatabase {
        /** @var string Transaction operation comes from the database class internally */
        const FLUSHING_INTERNAL = 'flush';
 
-       /** @var string No not remember the prior flags */
+       /** @var string Do not remember the prior flags */
        const REMEMBER_NOTHING = '';
        /** @var string Remember the prior flags */
        const REMEMBER_PRIOR = 'remember';
index f560cf1..dfa4c29 100644 (file)
@@ -196,9 +196,12 @@ abstract class LBFactory implements DestructibleService {
        /**
         * Prepare all tracked load balancers for shutdown
         * @param integer $flags Supports SHUTDOWN_* flags
-        * STUB
         */
        public function shutdown( $flags = 0 ) {
+               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
+                       $this->shutdownChronologyProtector( $this->chronProt );
+               }
+               $this->commitMasterChanges( __METHOD__ ); // sanity
        }
 
        /**
@@ -536,19 +539,3 @@ abstract class LBFactory implements DestructibleService {
        }
 
 }
-
-/**
- * Exception class for attempted DB access
- */
-class DBAccessError extends MWException {
-       public function __construct() {
-               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
-                       "This is not allowed, because database access has been disabled." );
-       }
-}
-
-/**
- * Exception class for replica DB wait timeouts
- */
-class DBReplicationWaitError extends Exception {
-}
index 4b9cccc..f201081 100644 (file)
@@ -418,11 +418,4 @@ class LBFactoryMulti extends LBFactory {
                        call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
                }
        }
-
-       public function shutdown( $flags = 0 ) {
-               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
-                       $this->shutdownChronologyProtector( $this->chronProt );
-               }
-               $this->commitMasterChanges( __METHOD__ ); // sanity
-       }
 }
index 3702c8b..c7c4752 100644 (file)
@@ -159,11 +159,4 @@ class LBFactorySimple extends LBFactory {
                        call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
                }
        }
-
-       public function shutdown( $flags = 0 ) {
-               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
-                       $this->shutdownChronologyProtector( $this->chronProt );
-               }
-               $this->commitMasterChanges( __METHOD__ ); // sanity
-       }
 }
index 6ce5829..8c019d8 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Logger\LegacyLogger;
+
 /**
  * New debugger system that outputs a toolbar on page view.
  *
@@ -93,7 +95,7 @@ class MWDebug {
         */
        public static function addModules( OutputPage $out ) {
                if ( self::$enabled ) {
-                       $out->addModules( 'mediawiki.debug.init' );
+                       $out->addModules( 'mediawiki.debug' );
                }
        }
 
@@ -334,6 +336,7 @@ class MWDebug {
                                if ( isset( $context['seconds_elapsed'] ) && isset( $context['memory_used'] ) ) {
                                        $prefix .= "{$context['seconds_elapsed']} {$context['memory_used']}  ";
                                }
+                               $str = LegacyLogger::interpolate( $str, $context );
                                $str = $prefix . $str;
                        }
                        self::$debug[] = rtrim( UtfNormal\Validator::cleanUp( $str ) );
@@ -525,12 +528,19 @@ class MWDebug {
                // see: https://github.com/facebook/hhvm/issues/2257#issuecomment-39362246
                $realMemoryUsage = wfIsHHVM();
 
+               $branch = GitInfo::currentBranch();
+               if ( GitInfo::isSHA1( $branch ) ) {
+                       // If it's a detached HEAD, the SHA1 will already be
+                       // included in the MW version, so don't show it.
+                       $branch = false;
+               }
+
                return [
                        'mwVersion' => $wgVersion,
                        'phpEngine' => wfIsHHVM() ? 'HHVM' : 'PHP',
                        'phpVersion' => wfIsHHVM() ? HHVM_VERSION : PHP_VERSION,
                        'gitRevision' => GitInfo::headSHA1(),
-                       'gitBranch' => GitInfo::currentBranch(),
+                       'gitBranch' => $branch,
                        'gitViewUrl' => GitInfo::headViewUrl(),
                        'time' => microtime( true ) - $wgRequestTime,
                        'log' => self::$log,
index 49ad9e6..f44ff1c 100644 (file)
@@ -39,73 +39,73 @@ use ObjectFactory;
  * global configuration variable used by LoggerFactory to construct its
  * default SPI provider:
  * @code
- * $wgMWLoggerDefaultSpi = array(
+ * $wgMWLoggerDefaultSpi = [
  *   'class' => '\\MediaWiki\\Logger\\MonologSpi',
- *   'args' => array( array(
- *       'loggers' => array(
- *           '@default' => array(
- *               'processors' => array( 'wiki', 'psr', 'pid', 'uid', 'web' ),
- *               'handlers'   => array( 'stream' ),
- *           ),
- *           'runJobs' => array(
- *               'processors' => array( 'wiki', 'psr', 'pid' ),
- *               'handlers'   => array( 'stream' ),
- *           )
- *       ),
- *       'processors' => array(
- *           'wiki' => array(
+ *   'args' => [ [
+ *       'loggers' => [
+ *           '@default' => [
+ *               'processors' => [ 'wiki', 'psr', 'pid', 'uid', 'web' ],
+ *               'handlers'   => [ 'stream' ],
+ *           ],
+ *           'runJobs' => [
+ *               'processors' => [ 'wiki', 'psr', 'pid' ],
+ *               'handlers'   => [ 'stream' ],
+ *           ]
+ *       ],
+ *       'processors' => [
+ *           'wiki' => [
  *               'class' => '\\MediaWiki\\Logger\\Monolog\\WikiProcessor',
- *           ),
- *           'psr' => array(
+ *           ],
+ *           'psr' => [
  *               'class' => '\\Monolog\\Processor\\PsrLogMessageProcessor',
- *           ),
- *           'pid' => array(
+ *           ],
+ *           'pid' => [
  *               'class' => '\\Monolog\\Processor\\ProcessIdProcessor',
- *           ),
- *           'uid' => array(
+ *           ],
+ *           'uid' => [
  *               'class' => '\\Monolog\\Processor\\UidProcessor',
- *           ),
- *           'web' => array(
+ *           ],
+ *           'web' => [
  *               'class' => '\\Monolog\\Processor\\WebProcessor',
- *           ),
- *       ),
- *       'handlers' => array(
- *           'stream' => array(
+ *           ],
+ *       ],
+ *       'handlers' => [
+ *           'stream' => [
  *               'class'     => '\\Monolog\\Handler\\StreamHandler',
- *               'args'      => array( 'path/to/your.log' ),
+ *               'args'      => [ 'path/to/your.log' ],
  *               'formatter' => 'line',
- *           ),
- *           'redis' => array(
+ *           ],
+ *           'redis' => [
  *               'class'     => '\\Monolog\\Handler\\RedisHandler',
- *               'args'      => array( function() {
+ *               'args'      => [ function() {
  *                       $redis = new Redis();
  *                       $redis->connect( '127.0.0.1', 6379 );
  *                       return $redis;
  *                   },
  *                   'logstash'
- *               ),
+ *               ],
  *               'formatter' => 'logstash',
  *               'buffer' => true,
- *           ),
- *           'udp2log' => array(
+ *           ],
+ *           'udp2log' => [
  *               'class' => '\\MediaWiki\\Logger\\Monolog\\LegacyHandler',
- *               'args' => array(
+ *               'args' => [
  *                   'udp://127.0.0.1:8420/mediawiki
- *               ),
+ *               ],
  *               'formatter' => 'line',
- *           ),
- *       ),
- *       'formatters' => array(
- *           'line' => array(
+ *           ],
+ *       ],
+ *       'formatters' => [
+ *           'line' => [
  *               'class' => '\\Monolog\\Formatter\\LineFormatter',
- *            ),
- *            'logstash' => array(
+ *            ],
+ *            'logstash' => [
  *                'class' => '\\Monolog\\Formatter\\LogstashFormatter',
- *                'args'  => array( 'mediawiki', php_uname( 'n' ), null, '', 1 ),
- *            ),
- *       ),
- *   ) ),
- * );
+ *                'args'  => [ 'mediawiki', php_uname( 'n' ), null, '', 1 ],
+ *            ],
+ *       ],
+ *   ] ],
+ * ];
  * @endcode
  *
  * @see https://github.com/Seldaek/monolog
index 5e02c5c..ec7360e 100644 (file)
@@ -79,6 +79,16 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
         */
        private $linkDeletions = null;
 
+       /**
+        * @var null|array Added properties if calculated.
+        */
+       private $propertyInsertions = null;
+
+       /**
+        * @var null|array Deleted properties if calculated.
+        */
+       private $propertyDeletions = null;
+
        /**
         * @var User|null
         */
@@ -234,12 +244,13 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
 
                # Page properties
                $existing = $this->getExistingProperties();
-               $propertiesDeletes = $this->getPropertyDeletions( $existing );
-               $this->incrTableUpdate( 'page_props', 'pp', $propertiesDeletes,
+               $this->propertyDeletions = $this->getPropertyDeletions( $existing );
+               $this->incrTableUpdate( 'page_props', 'pp', $this->propertyDeletions,
                        $this->getPropertyInsertions( $existing ) );
 
                # Invalidate the necessary pages
-               $changed = $propertiesDeletes + array_diff_assoc( $this->mProperties, $existing );
+               $this->propertyInsertions = array_diff_assoc( $this->mProperties, $existing );
+               $changed = $this->propertyDeletions + $this->propertyInsertions;
                $this->invalidateProperties( $changed );
 
                # Refresh links of all pages including this page
@@ -1016,6 +1027,26 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                return $result;
        }
 
+       /**
+        * Fetch page properties added by this LinksUpdate.
+        * Only available after the update is complete.
+        * @since 1.28
+        * @return null|array
+        */
+       public function getAddedProperties() {
+               return $this->propertyInsertions;
+       }
+
+       /**
+        * Fetch page properties removed by this LinksUpdate.
+        * Only available after the update is complete.
+        * @since 1.28
+        * @return null|array
+        */
+       public function getRemovedProperties() {
+               return $this->propertyDeletions;
+       }
+
        /**
         * Update links table freshness
         */
index 25b4cca..8604ba2 100644 (file)
@@ -602,7 +602,7 @@ abstract class HTMLFormField {
                }
 
                $fieldType = get_class( $this );
-               $helpText = $this->getHelpText();
+               $help = $this->getHelpText();
                $errors = $this->getErrorsRaw( $value );
                foreach ( $errors as &$error ) {
                        $error = new OOUI\HtmlSnippet( $error );
@@ -616,7 +616,7 @@ abstract class HTMLFormField {
                $config = [
                        'classes' => [ "mw-htmlform-field-$fieldType", $this->mClass ],
                        'align' => $this->getLabelAlignOOUI(),
-                       'help' => $helpText !== null ? new OOUI\HtmlSnippet( $helpText ) : null,
+                       'help' => ( $help !== null && $help !== '' ) ? new OOUI\HtmlSnippet( $help ) : null,
                        'errors' => $errors,
                        'notices' => $notices,
                        'infusable' => $infusable,
index d508d76..eafb9d4 100644 (file)
@@ -1437,10 +1437,10 @@ abstract class Installer {
 
        /**
         * Get an array of install steps. Should always be in the format of
-        * array(
+        * [
         *   'name'     => 'someuniquename',
-        *   'callback' => array( $obj, 'method' ),
-        * )
+        *   'callback' => [ $obj, 'method' ],
+        * ]
         * There must be a config-install-$name message defined per step, which will
         * be shown on install.
         *
@@ -1724,7 +1724,7 @@ abstract class Installer {
         * Add an installation step following the given step.
         *
         * @param callable $callback A valid installation callback array, in this form:
-        *    array( 'name' => 'some-unique-name', 'callback' => array( $obj, 'function' ) );
+        *    [ 'name' => 'some-unique-name', 'callback' => [ $obj, 'function' ] ];
         * @param string $findStep The step to find. Omit to put the step at the beginning
         */
        public function addInstallStep( $callback, $findStep = 'BEGINNING' ) {
index 1d7c7f2..a9e3e85 100644 (file)
@@ -98,7 +98,7 @@ class LocalSettingsGenerator {
         * For $wgGroupPermissions, set a given ['group']['permission'] value.
         * @param string $group Group name
         * @param array $rightsArr An array of permissions, in the form of:
-        *   array( 'right' => true, 'right2' => false )
+        *   [ 'right' => true, 'right2' => false ]
         */
        public function setGroupRights( $group, $rightsArr ) {
                $this->groupPermissions[$group] = $rightsArr;
index 719b66a..65af086 100644 (file)
@@ -155,7 +155,6 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addField', 'ipblocks', 'ipb_allow_usertalk', 'patch-ipb_allow_usertalk.sql' ],
 
                        // 1.15
-                       [ 'doUniquePlTlIl' ],
                        [ 'addTable', 'change_tag', 'patch-change_tag.sql' ],
                        [ 'addTable', 'tag_summary', 'patch-tag_summary.sql' ],
                        [ 'addTable', 'valid_tag', 'patch-valid_tag.sql' ],
@@ -287,6 +286,8 @@ class MysqlUpdater extends DatabaseUpdater {
                        // 1.28
                        [ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
                                'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
+                       [ 'doRevisionPageRevIndexNonUnique' ],
+                       [ 'doNonUniquePlTlIl' ],
                ];
        }
 
@@ -973,24 +974,24 @@ class MysqlUpdater extends DatabaseUpdater {
                return true;
        }
 
-       protected function doUniquePlTlIl() {
+       protected function doNonUniquePlTlIl() {
                $info = $this->db->indexInfo( 'pagelinks', 'pl_namespace' );
-               if ( is_array( $info ) && !$info[0]->Non_unique ) {
-                       $this->output( "...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" );
+               if ( is_array( $info ) && $info[0]->Non_unique ) {
+                       $this->output( "...pl_namespace, tl_namespace, il_to indices are already non-UNIQUE.\n" );
 
                        return true;
                }
                if ( $this->skipSchema ) {
                        $this->output( "...skipping schema change (making pl_namespace, tl_namespace " .
-                               "and il_to indices UNIQUE).\n" );
+                               "and il_to indices non-UNIQUE).\n" );
 
                        return false;
                }
 
                return $this->applyPatch(
-                       'patch-pl-tl-il-unique.sql',
+                       'patch-pl-tl-il-nonunique.sql',
                        false,
-                       'Making pl_namespace, tl_namespace and il_to indices UNIQUE'
+                       'Making pl_namespace, tl_namespace and il_to indices non-UNIQUE'
                );
        }
 
@@ -1101,4 +1102,24 @@ class MysqlUpdater extends DatabaseUpdater {
                        'Making user_id unsigned int'
                );
        }
+
+       protected function doRevisionPageRevIndexNonUnique() {
+               if ( !$this->doTable( 'revision' ) ) {
+                       return true;
+               } elseif ( !$this->db->indexExists( 'revision', 'rev_page_id' ) ) {
+                       $this->output( "...rev_page_id index not found on revision.\n" );
+                       return true;
+               }
+
+               if ( !$this->db->indexUnique( 'revision', 'rev_page_id' ) ) {
+                       $this->output( "...rev_page_id index already non-unique.\n" );
+                       return true;
+               }
+
+               return $this->applyPatch(
+                       'patch-revision-page-rev-index-nonunique.sql',
+                       false,
+                       'Making rev_page_id index non-unique'
+               );
+       }
 }
index b29e3bd..c9ebe32 100644 (file)
        "config-page-language": "Zıwan",
        "config-page-welcome": "Şıma xeyr ameyê MediaWiki!",
        "config-page-dbconnect": "Database rê grêdey",
+       "config-page-upgrade": "Est bıyaye versiyoni berz kı",
+       "config-page-dbsettings": "Sazê Database",
        "config-page-name": "Name",
        "config-page-options": "Weçinegi",
        "config-page-install": "Barine",
        "config-page-complete": "Temamyayo",
+       "config-page-restart": "Barkerdışi fına ser kı",
        "config-page-readme": "Mı bıwane",
        "config-page-copying": "Kopyayeno",
        "config-page-upgradedoc": "Berzkerdış",
        "config-restart": "E, fına dest pekê",
        "config-sidebar": "* [https://www.mediawiki.org MediaWiki keye]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Şınasiya Karberi]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Şınasiya İdarekaran]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Peşti]\n----\n* <doclink href=Readme>Mı buwanê</doclink>\n* <doclink href=ReleaseNotes>Notê elaqeyıni</doclink>\n* <doclink href=Copying>Kopyakerdış</doclink>\n* <doclink href=UpgradeDoc>Zêdekerdış</doclink>",
        "config-env-php": "PHP $1 i biyo saz.",
+       "config-env-hhvm": "HHVM $1 saz bi ya.",
        "config-db-type": "Database tipe:",
        "config-db-host": "Database host:",
        "config-db-host-oracle": "Database TNS:",
index 16c9331..3afbaa3 100644 (file)
@@ -44,6 +44,9 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
         *   - HTTPProxy      : HTTP proxy to use (optional)
         *   - parsoidCompat  : whether to parse URL as if they were meant for Parsoid
         *                       boolean (optional)
+        *   - fixedUrl       : Do not append domain to the url. For example to use
+        *                       English Wikipedia restbase, you would this to true
+        *                       and url to https://en.wikipedia.org/api/rest_#version#
         */
        public function __construct( array $params ) {
                // set up defaults and merge them with the given params
@@ -54,7 +57,8 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
                        'timeout' => 100,
                        'forwardCookies' => false,
                        'HTTPProxy' => null,
-                       'parsoidCompat' => false
+                       'parsoidCompat' => false,
+                       'fixedUrl' => false,
                ], $params );
                // Ensure that the url parameter has a trailing slash.
                $mparams['url'] = preg_replace(
@@ -81,10 +85,18 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
 
                $result = [];
                foreach ( $reqs as $key => $req ) {
-                       // replace /local/ with the current domain
-                       $req['url'] = preg_replace( '#^local/#', $this->params['domain'] . '/', $req['url'] );
-                       // and prefix it with the service URL
-                       $req['url'] = $this->params['url'] . $req['url'];
+                       if ( $this->params['fixedUrl'] ) {
+                               $version = explode( '/', $req['url'] )[1];
+                               $req['url'] =
+                                       str_replace( '#version#', $version, $this->params['url'] ) .
+                                       preg_replace( '#^local/v./#', '', $req['url'] );
+                       } else {
+                               // replace /local/ with the current domain
+                               $req['url'] = preg_replace( '#^local/#', $this->params['domain'] . '/', $req['url'] );
+                               // and prefix it with the service URL
+                               $req['url'] = $this->params['url'] . $req['url'];
+                       }
+
                        // set the appropriate proxy, timeout and headers
                        if ( $this->params['HTTPProxy'] ) {
                                $req['proxy'] = $this->params['HTTPProxy'];
@@ -99,7 +111,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
                }
 
                return $result;
-
        }
 
        /**
index bb760bd..aefda79 100644 (file)
@@ -42,6 +42,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
         *   - serializer:          May be either "php" or "igbinary". Igbinary produces more compact
         *                          values, but serialization is much slower unless the php.ini option
         *                          igbinary.compact_strings is off.
+        *   - use_binary_protocol  Whether to enable the binary protocol (default is ASCII) (boolean)
         * @param array $params
         * @throws InvalidArgumentException
         */
@@ -62,8 +63,8 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                        $this->client = new Memcached;
                }
 
-               if ( !isset( $params['serializer'] ) ) {
-                       $params['serializer'] = 'php';
+               if ( $params['use_binary_protocol'] ) {
+                       $this->client->setOption( Memcached::OPT_BINARY_PROTOCOL, true );
                }
 
                if ( isset( $params['retry_timeout'] ) ) {
@@ -119,6 +120,20 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                $this->client->addServers( $servers );
        }
 
+       protected function applyDefaultParams( $params ) {
+               $params = parent::applyDefaultParams( $params );
+
+               if ( !isset( $params['use_binary_protocol'] ) ) {
+                       $params['use_binary_protocol'] = false;
+               }
+
+               if ( !isset( $params['serializer'] ) ) {
+                       $params['serializer'] = 'php';
+               }
+
+               return $params;
+       }
+
        protected function getWithToken( $key, &$casToken, $flags = 0 ) {
                $this->debugLog( "get($key)" );
                $result = $this->client->get( $this->validateKeyEncoding( $key ), null, $casToken );
index b3a97f7..e299f7e 100644 (file)
@@ -149,6 +149,15 @@ class Article implements Page {
                return $article;
        }
 
+       /**
+        * Get the page this view was redirected from
+        * @return Title|null
+        * @since 1.28
+        */
+       public function getRedirectedFrom() {
+               return $this->mRedirectedFrom;
+       }
+
        /**
         * Tell the page view functions that this view was redirected
         * from another page on the wiki.
@@ -467,7 +476,7 @@ class Article implements Page {
         * page of the given title.
         */
        public function view() {
-               global $wgUseFileCache, $wgDebugToolbar, $wgMaxRedirects;
+               global $wgUseFileCache, $wgDebugToolbar;
 
                # Get variables from query string
                # As side effect this will load the revision and update the title
@@ -520,29 +529,6 @@ class Article implements Page {
 
                # Try client and file cache
                if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
-                       # Use the greatest of the page's timestamp or the timestamp of any
-                       # redirect in the chain (bug 67849)
-                       $timestamp = $this->mPage->getTouched();
-                       if ( isset( $this->mRedirectedFrom ) ) {
-                               $timestamp = max( $timestamp, $this->mRedirectedFrom->getTouched() );
-
-                               # If there can be more than one redirect in the chain, we have
-                               # to go through the whole chain too in case an intermediate
-                               # redirect was changed.
-                               if ( $wgMaxRedirects > 1 ) {
-                                       $titles = Revision::newFromTitle( $this->mRedirectedFrom )
-                                               ->getContent( Revision::FOR_THIS_USER, $user )
-                                               ->getRedirectChain();
-                                       $thisTitle = $this->getTitle();
-                                       foreach ( $titles as $title ) {
-                                               if ( Title::compare( $title, $thisTitle ) === 0 ) {
-                                                       break;
-                                               }
-                                               $timestamp = max( $timestamp, $title->getTouched() );
-                                       }
-                               }
-                       }
-
                        # Try to stream the output from file cache
                        if ( $wgUseFileCache && $this->tryFileCache() ) {
                                wfDebug( __METHOD__ . ": done file cache\n" );
index 4066501..e1d9f99 100644 (file)
@@ -2883,7 +2883,14 @@ class WikiPage implements Page, IDBAccessObject {
                // unless they actually try to catch exceptions (which is rare).
 
                // we need to remember the old content so we can use it to generate all deletion updates.
-               $content = $this->getContent( Revision::RAW );
+               try {
+                       $content = $this->getContent( Revision::RAW );
+               } catch ( Exception $ex ) {
+                       wfLogWarning( __METHOD__ . ': failed to load content during deletion! '
+                               . $ex->getMessage() );
+
+                       $content = null;
+               }
 
                // Bitfields to further suppress the content
                if ( $suppress ) {
@@ -3024,8 +3031,16 @@ class WikiPage implements Page, IDBAccessObject {
         *   may already return null when the page proper was deleted.
         */
        public function doDeleteUpdates( $id, Content $content = null ) {
+               try {
+                       $countable = $this->isCountable();
+               } catch ( Exception $ex ) {
+                       // fallback for deleting broken pages for which we cannot load the content for
+                       // some reason. Note that doDeleteArticleReal() already logged this problem.
+                       $countable = false;
+               }
+
                // Update site status
-               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
+               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$countable, -1 ) );
 
                // Delete pagelinks, update secondary indexes, etc
                $updates = $this->getDeletionUpdates( $content );
@@ -3641,7 +3656,14 @@ class WikiPage implements Page, IDBAccessObject {
                if ( !$content ) {
                        // load content object, which may be used to determine the necessary updates.
                        // XXX: the content may not be needed to determine the updates.
-                       $content = $this->getContent( Revision::RAW );
+                       try {
+                               $content = $this->getContent( Revision::RAW );
+                       } catch ( Exception $ex ) {
+                               // If we can't load the content, something is wrong. Perhaps that's why
+                               // the user is trying to delete the page, so let's not fail in that case.
+                               // Note that doDeleteArticleReal() will already have logged an issue with
+                               // loading the content.
+                       }
                }
 
                if ( !$content ) {
index b116bd4..035baac 100644 (file)
@@ -906,11 +906,11 @@ class Parser {
         * the form:
         *
         * @code
-        *   'UNIQ-xxxxx' => array(
+        *   'UNIQ-xxxxx' => [
         *     'element',
         *     'tag content',
-        *     array( 'param' => 'x' ),
-        *     '<element param="x">tag content</element>' ) )
+        *     [ 'param' => 'x' ],
+        *     '<element param="x">tag content</element>' ]
         * @endcode
         *
         * @param array $elements List of element names. Comments are always extracted.
index 79b71df..30fe3ae 100644 (file)
@@ -175,8 +175,7 @@ class ResourceLoaderContext {
                        // Stricter version of RequestContext::sanitizeLangCode()
                        if ( !Language::isValidBuiltInCode( $lang ) ) {
                                wfDebug( "Invalid user language code\n" );
-                               global $wgLanguageCode;
-                               $lang = $wgLanguageCode;
+                               $lang = $this->getResourceLoader()->getConfig()->get( 'LanguageCode' );
                        }
                        $this->language = $lang;
                }
index 48e7937..de89fc7 100644 (file)
@@ -264,8 +264,8 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         *
         * @param ResourceLoaderContext $context
         * @return array List of CSS strings or array of CSS strings keyed by media type.
-        *  like array( 'screen' => '.foo { width: 0 }' );
-        *  or array( 'screen' => array( '.foo { width: 0 }' ) );
+        *  like [ 'screen' => '.foo { width: 0 }' ];
+        *  or [ 'screen' => [ '.foo { width: 0 }' ] ];
         */
        public function getStyles( ResourceLoaderContext $context ) {
                // Stub, override expected
@@ -279,7 +279,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         * load the files directly. See also getScriptURLsForDebug()
         *
         * @param ResourceLoaderContext $context
-        * @return array Array( mediaType => array( URL1, URL2, ... ), ... )
+        * @return array [ mediaType => [ URL1, URL2, ... ], ... ]
         */
        public function getStyleURLsForDebug( ResourceLoaderContext $context ) {
                $resourceLoader = $context->getResourceLoader();
@@ -637,7 +637,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                // Styles
                if ( $context->shouldIncludeStyles() ) {
                        $styles = [];
-                       // Don't create empty stylesheets like array( '' => '' ) for modules
+                       // Don't create empty stylesheets like [ '' => '' ] for modules
                        // that don't *have* any stylesheets (bug 38024).
                        $stylePairs = $this->getStyles( $context );
                        if ( count( $stylePairs ) ) {
index 46808a1..79922bf 100644 (file)
@@ -50,4 +50,11 @@ class ResourceLoaderSiteStylesModule extends ResourceLoaderWikiModule {
        public function getType() {
                return self::LOAD_STYLES;
        }
+
+       /**
+        * @return string
+        */
+       public function getGroup() {
+               return 'site';
+       }
 }
index bf73d3f..263cb11 100644 (file)
@@ -722,6 +722,8 @@ final class SessionBackend {
                        }
                }
 
+               $flags = $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY;
+               $flags |= CachedBagOStuff::WRITE_SYNC; // write to all datacenters
                $this->store->set(
                        wfMemcKey( 'MWSession', (string)$this->id ),
                        [
@@ -729,7 +731,7 @@ final class SessionBackend {
                                'metadata' => $metadata,
                        ],
                        $metadata['expires'],
-                       $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY
+                       $flags
                );
 
                $this->metaDirty = false;
index 22c38cb..c3d43df 100644 (file)
@@ -835,6 +835,12 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                                'class' => 'mw-ui-flush-right mw-secure',
                        ], $this->msg( 'userlogin-signwithsecure' )->text() );
                }
+               $usernameHelpLink = '';
+               if ( !$this->msg( 'createacct-helpusername' )->isDisabled() ) {
+                       $usernameHelpLink = Html::rawElement( 'span', [
+                               'class' => 'mw-ui-flush-right',
+                       ], $this->msg( 'createacct-helpusername' )->parse() );
+               }
 
                if ( $this->isSignup() ) {
                        $fieldDefinitions = [
@@ -847,9 +853,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                                        'weight' => -105,
                                ],
                                'username' => [
-                                       'label-message' => 'userlogin-yourname',
-                                       // FIXME help-message does not match old formatting
-                                       'help-message' => 'createacct-helpusername',
+                                       'label-raw' => $this->msg( 'userlogin-yourname' )->escaped() . $usernameHelpLink,
                                        'id' => 'wpName2',
                                        'placeholder-message' => $isLoggedIn ? 'createacct-another-username-ph'
                                                : 'userlogin-yourname-ph',
index 7c7f017..de58762 100644 (file)
@@ -136,8 +136,7 @@ class SpecialBlockList extends SpecialPage {
                                case Block::TYPE_IP:
                                case Block::TYPE_RANGE:
                                        list( $start, $end ) = IP::parseRange( $target );
-                                       $dbr = wfGetDB( DB_SLAVE );
-                                       $conds[] = $dbr->makeList(
+                                       $conds[] = wfGetDB( DB_SLAVE )->makeList(
                                                [
                                                        'ipb_address' => $target,
                                                        Block::getRangeCond( $start, $end )
index 5322a04..61b6a8c 100644 (file)
@@ -188,6 +188,9 @@ class SpecialPageLanguage extends FormSpecialPage {
                $logid = $entry->insert();
                $entry->publish( $logid );
 
+               // Force re-render so that language-based content (parser functions etc.) gets updated
+               $title->invalidateCache();
+
                return true;
        }
 
index f00477f..3697e5d 100644 (file)
@@ -53,10 +53,10 @@ class SpecialPreferences extends SpecialPage {
                $out->addModules( 'mediawiki.special.preferences' );
                $out->addModuleStyles( 'mediawiki.special.preferences.styles' );
 
-               $request = $this->getRequest();
-               if ( $request->getSessionData( 'specialPreferencesSaveSuccess' ) ) {
+               $session = $this->getRequest()->getSession();
+               if ( $session->get( 'specialPreferencesSaveSuccess' ) ) {
                        // Remove session data for the success message
-                       $request->setSessionData( 'specialPreferencesSaveSuccess', null );
+                       $session->remove( 'specialPreferencesSaveSuccess' );
                        $out->addModuleStyles( 'mediawiki.notification.convertmessagebox.styles' );
 
                        $out->addHtml(
@@ -146,7 +146,7 @@ class SpecialPreferences extends SpecialPage {
                $user->saveSettings();
 
                // Set session data for the success message
-               $this->getRequest()->setSessionData( 'specialPreferencesSaveSuccess', 1 );
+               $this->getRequest()->getSession()->set( 'specialPreferencesSaveSuccess', 1 );
 
                $url = $this->getPageTitle()->getFullURL();
                $this->getOutput()->redirect( $url );
index 7b058c1..adc1dd8 100644 (file)
@@ -241,6 +241,11 @@ class UsersPager extends AlphabeticPager {
                        $cache[intval( $row->ug_user )][] = $row->ug_group;
                        $groups[$row->ug_group] = true;
                }
+
+               // Give extensions a chance to add things like global user group data
+               // into the cache array to ensure proper output later on
+               Hooks::run( 'UsersPagerDoBatchLookups', [ $dbr, $userIds, &$cache, &$groups ] );
+
                $this->userGroupCache = $cache;
 
                // Add page of groups to link batch
index e2f7763..b37c831 100644 (file)
@@ -1659,7 +1659,7 @@ abstract class UploadBase {
         * @return array Containing the namespace URI and prefix
         */
        private static function splitXmlNamespace( $element ) {
-               // 'http://www.w3.org/2000/svg:script' -> array( 'http://www.w3.org/2000/svg', 'script' )
+               // 'http://www.w3.org/2000/svg:script' -> [ 'http://www.w3.org/2000/svg', 'script' ]
                $parts = explode( ':', strtolower( $element ) );
                $name = array_pop( $parts );
                $ns = implode( ':', $parts );
index cb3b4b8..169e0ff 100644 (file)
@@ -1037,6 +1037,7 @@ class Language {
         *    xiy  y (two digit year) in Iranian calendar
         *    xiY  Y (full year) in Iranian calendar
         *    xit  t (days in month) in Iranian calendar
+        *    xiz  z (day of the year) in Iranian calendar
         *
         *    xjj  j (day number) in Hebrew calendar
         *    xjF  F (month name) in Hebrew calendar
@@ -1339,6 +1340,13 @@ class Language {
                                        }
                                        $num = self::$IRANIAN_DAYS[$iranian[1] - 1];
                                        break;
+                               case 'xiz':
+                                       $usedIranianYear = true;
+                                       if ( !$iranian ) {
+                                               $iranian = self::tsToIranian( $ts );
+                                       }
+                                       $num = $iranian[3];
+                                       break;
                                case 'a':
                                        $usedAMPM = true;
                                        $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'am' : 'pm';
@@ -1597,6 +1605,8 @@ class Language {
                        $jDayNo = floor( ( $jDayNo - 1 ) % 365 );
                }
 
+               $jz = $jDayNo;
+
                for ( $i = 0; $i < 11 && $jDayNo >= self::$IRANIAN_DAYS[$i]; $i++ ) {
                        $jDayNo -= self::$IRANIAN_DAYS[$i];
                }
@@ -1604,7 +1614,7 @@ class Language {
                $jm = $i + 1;
                $jd = $jDayNo + 1;
 
-               return [ $jy, $jm, $jd ];
+               return [ $jy, $jm, $jd, $jz ];
        }
 
        /**
index 97a8233..cb869d0 100644 (file)
        "passwordreset-emailtext-user": "احد ما (قد يكون انت$1)طلب مذكرة تفاصيل الحساب ل{{SITENAME}} ($4).المستخدم الاتي {{PLURAL:$3|الحساب هو|الحسابات هي}} قد قرن بهذا العنوان :\n\n$2\n\n{{PLURAL:$3|كلمة المرور المؤقتة|كلمات المرور المؤقة}}سينتهي في {{PLURAL:$5|يوم|ايام$5 }}\nمن الافضل ان تسجل الدخول وتختار كلمة مرور جديدة الان .\nإذا قام شخص آخر بهذا الطلب، أو إذا  تذكرت كلمة المرور الأصلية الخاصة بك،ولم تعد ترغب في تغييره، يمكنك تجاهل هذه الرسالة ومتابعة استخدام  كلمة المرورالقديمة.",
        "passwordreset-emailelement": "اسم المستخدم: \n$1\n\nكلمة السر المؤقتة: \n$2",
        "passwordreset-emailsentemail": "أرسل بريد إلكتروني تذكيري",
-       "passwordreset-emailsent-capture": "أرسل بريد إلكتروني تذكيري وهو معروض بالأسفل.",
-       "passwordreset-emailerror-capture": "ولّد بريد إلكتروني تذكيري وهو معروض بالأسفل لكن فشل إرساله للمستخدم: $1",
        "changeemail": "تغيير عنوان البريد الإلكتروني",
        "changeemail-header": "تغيير عنوان البريد الإلكتروني للحساب",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
        "undo-norev": "فشل في الرجوع عن التعديل حيث أنه غير موجود أو تم حذفه.",
        "undo-summary": "الرجوع عن التعديل $1 بواسطة [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]])",
-       "cantcreateaccounttitle": "لا يمكن إنشاء حساب",
        "cantcreateaccount-text": "إنشاء الحسابات من عنوان الأيبي هذا ('''$1''') تم منعه بواسطة [[User:$3|$3]].\n\nالسبب المعطى بواسطة $3 هو ''$2''",
        "viewpagelogs": "اعرض سجلات هذه الصفحة",
        "nohistory": "لا يوجد تاريخ للتعديلات لهذه الصفحة.",
        "revdel-restore": "تغيير الرؤية",
        "pagehist": "تاريخ صفحة",
        "deletedhist": "التاريخ المحذوف",
-       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø­فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
+       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø®فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
        "revdelete-show-no-access": "خطأ في إظهار العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-no-access": "خطأ في تعديل العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-missing": "خطأ في تعديل العنصر ذا الهوية $1: العنصر مفقود من قاعدة البيانات!",
index 3b40a05..1d40a9e 100644 (file)
@@ -64,7 +64,9 @@
                        "Alaa",
                        "Izoozo",
                        "علاء",
-                       "Hhaboh162002"
+                       "Hhaboh162002",
+                       "بدارين",
+                       "باسم"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "october-date": "تشرين الأول/أكتوبر $1",
        "november-date": "تشرين الثاني/نوفمبر $1",
        "december-date": "كانون الأول/ديسمبر $1",
-       "period-am": "صباحا",
+       "period-am": "صباحًا",
        "period-pm": "مساءً",
        "pagecategories": "{{PLURAL:$1|بلا تصنيف|تصنيف|تصنيفان|تصنيفات}}",
        "category_header": "صفحات تصنيف «$1»",
        "tagline": "من {{SITENAME}}",
        "help": "مساعدة",
        "search": "بحث",
-       "search-ignored-headings": "# <!-- Ø£ØªØ±Ù\83 Ù\87ذا Ø§Ù\84سطر Ù\83Ù\85ا Ù\87Ù\88 --> <pre>\n# Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84 Ø§Ù\84ترÙ\88Ù\8aسات Ø®Ù\84اÙ\84 Ø¹Ù\85Ù\84Ù\8aØ© Ø§Ù\84بحث\n#ا Ù\84تغÙ\8aÙ\8aرات Ø³ØªØ£Ø®Ø° Ù\85جراÙ\87ا Ù\85ا Ø£Ù\86 Ù\8aتÙ\85 Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ø§Ù\84تÙ\8a ØªØ­ØªÙ\88Ù\8a Ø¹Ù\84Ù\89 ØªØ±Ù\88Ù\8aسات\n# Ù\8aÙ\85Ù\83Ù\86Ù\83 Ù\81رض Ø¹Ù\85Ù\84Ù\8aØ© Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ù\85Ù\86 Ø®Ù\84اÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ù\81ارغ\n# Ø§Ù\84صÙ\8aغة Ù\87Ù\8a Ù\83اÙ\84أتÙ\8a:\n# * Ù\83Ù\84 Ù\85ا Ù\8aÙ\83تب Ø¨Ø¹Ø¯ \"#\" Ø¥Ù\84Ù\89 Ø¢Ø®Ø± Ø§Ù\84سطر Ù\8aعتبر ØªØ¹Ù\84Ù\8aÙ\82\n# * Ù\83Ù\84 Ø³Ø·Ø± ØºÙ\8aر Ù\81ارغ Ø³Ù\8aÙ\83Ù\88Ù\86 Ø§Ù\84عÙ\86Ù\88اÙ\86 Ø§Ù\84Ø°Ù\8a Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84Ù\87 (سÙ\8aأخذ Ø§Ù\84عÙ\86Ù\88اÙ\86 Ù\83Ù\85ا Ù\87Ù\88 Ø¨Ø§Ù\84ضبط Ø¨Ø§Ù\84تشÙ\83Ù\8aÙ\84 Ù\88Ø®Ù\84اÙ\81Ù\87)\nاÙ\84Ù\85راجع\nاÙ\84Ù\88صÙ\84ات Ø§Ù\84خارجÙ\8aØ©\nØ£نظر أيضا\n#</pre><!--أترك هذا السطر كما هو -->",
+       "search-ignored-headings": "# <!-- Ø§ØªØ±Ù\83 Ù\87ذا Ø§Ù\84سطر Ù\83Ù\85ا Ù\87Ù\88 --> <pre>\n# Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84 Ø§Ù\84ترÙ\88Ù\8aسات Ø®Ù\84اÙ\84 Ø¹Ù\85Ù\84Ù\8aØ© Ø§Ù\84بحث\n#اÙ\84تغÙ\8aÙ\8aرات Ø³ØªØ£Ø®Ø° Ù\85جراÙ\87ا Ù\85ا Ø£Ù\86 Ù\8aتÙ\85 Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ø§Ù\84تÙ\8a ØªØ­ØªÙ\88Ù\8a Ø¹Ù\84Ù\89 ØªØ±Ù\88Ù\8aسات\n# Ù\8aÙ\85Ù\83Ù\86Ù\83 Ù\81رض Ø¹Ù\85Ù\84Ù\8aØ© Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ù\85Ù\86 Ø®Ù\84اÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ù\81ارغ\n# Ø§Ù\84صÙ\8aغة Ù\87Ù\8a Ù\83اÙ\84أتÙ\8a:\n# * Ù\83Ù\84 Ù\85ا Ù\8aÙ\83تب Ø¨Ø¹Ø¯ \"#\" Ø¥Ù\84Ù\89 Ø¢Ø®Ø± Ø§Ù\84سطر Ù\8aعتبر ØªØ¹Ù\84Ù\8aÙ\82\n# * Ù\83Ù\84 Ø³Ø·Ø± ØºÙ\8aر Ù\81ارغ Ø³Ù\8aÙ\83Ù\88Ù\86 Ø§Ù\84عÙ\86Ù\88اÙ\86 Ø§Ù\84Ø°Ù\8a Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84Ù\87 (سÙ\8aأخذ Ø§Ù\84عÙ\86Ù\88اÙ\86 Ù\83Ù\85ا Ù\87Ù\88 Ø¨Ø§Ù\84ضبط Ø¨Ø§Ù\84تشÙ\83Ù\8aÙ\84 Ù\88Ø®Ù\84اÙ\81Ù\87)\nاÙ\84Ù\85راجع\nاÙ\84Ù\88صÙ\84ات Ø§Ù\84خارجÙ\8aØ©\nانظر أيضا\n#</pre><!--أترك هذا السطر كما هو -->",
        "searchbutton": "ابحث",
        "go": "اذهب",
        "searcharticle": "اذهب",
        "databaseerror": "عطل في قاعدة البيانات",
        "databaseerror-text": "حدث خطأ في إستعلام قاعدة البيانات. قد يشير هذا إلى خطأ في البرنامج.",
        "databaseerror-textcl": "حدث خطأ في إستعلام قاعدة البيانات.",
-       "databaseerror-query": "Ø¥ستعلام: $1",
+       "databaseerror-query": "استعلام: $1",
        "databaseerror-function": "دالة: $1",
        "databaseerror-error": "خطأ: $1",
+       "transaction-duration-limit-exceeded": "لتفادي إنشاء تأخير نسخ عالي، هذا الفعل تم إنهاؤه لأن فترة الكتابة ($1) تجاوزت حد $2 ثانية.\nلو أنك تغير عناصر عديدة في نفس الوقت، حاول تجربة عمليا عديدة أصغر بدلا من ذلك.",
        "laggedslavemode": "'''تحذير:''' الصفحة قد لا تحتوي على أحدث التحديثات.",
        "readonly": "قاعدة البيانات مقفلة",
        "enterlockreason": "أدخل سببا للقفل ذاكرا تقديرا لوقت إزالة الغلق",
        "missingarticle-rev": "(رقم المراجعة: $1)",
        "missingarticle-diff": "(فرق: $1، $2)",
        "readonly_lag": "تم قفل قاعدة البيانات تلقائيا حتى تستطيع الخواديم التابعة ملاحقة الخادوم الرئيسي",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP header تم إرساله لكن الطلب كان لAPI write module.",
        "internalerror": "عطل داخلي",
        "internalerror_info": "عطل داخلي: $1",
        "internalerror-fatal-exception": "استثناء مميت من النوع \"$1\"",
        "title-invalid-interwiki": "عنوان الصفحة المطلوب يتضمن وصلة لحلقة لغة وهو ما لا يمكن استخدامه في العناوين.",
        "title-invalid-talk-namespace": "عنوان الصفحة المطلوبة يشير إلى صفحة نقاش غير موجودة.",
        "title-invalid-characters": "عنوان الصفحة المطلوب يتضمن رموزًا غير صالحة: \"$1\"",
+       "title-invalid-relative": "العنوان به مسار نسبي. عنوان الصفحات النسبية (./, ../) هي غير صحيحة، لأنها ستكون غاليا لا يمكن الوصول لها عندما يتم التعامل معها بواسطة متصفح المستخدم.",
+       "title-invalid-magic-tilde": "عنوان الصفحة المطلوب يحتوي على تتابع الشر السحري غير الصحيح (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "عنوان الصفحة المطلوبة طويل جدا. يجب أن يكون ليس أطول من $1 {{PLURAL:$1|بايت}} باستخدام ترميز UTF-8.",
        "title-invalid-leading-colon": "عنوان الصفحة المطلوب يتضمن فاصلة غير صالحة في بدايته.",
        "perfcached": "البيانات التالية مخبأة و قد لا تكون محدثة. {{PLURAL:$1||نتيجة واحدة|نتيجتان|$1 نتائج|$1 نتيجة}} على الأكثر {{PLURAL:$1||مخبّأة|مخبّأتان|مخبّأة}}.",
        "perfcachedts": "البيانات التالية مخزنة، وكان آخر تحديث لها في $1. العدد الأقصى للنتائج المخزنة هو {{PLURAL:$4||نتيجة واحدة|نتيجتان|$4 نتائج|$4 نتيجة}}.",
        "nocookiesnew": "تم إنشاء حساب المستخدم، ولكنك لست مسجل الدخول بعد.\nيستخدم {{SITENAME}} كوكيز لتسجيل الدخول.\nلديك الكوكيز معطلة.\nمن فضلك فعلها، ثم سجل الدخول باسم المستخدم وكلمة السر الجديدين.",
        "nocookieslogin": "يستخدم {{SITENAME}} الكوكيز لتسجيل الدخول.\nالكوكيز معطلة لديك.\nمن فضلك فعلها ثم حاول مرة أخرى.",
        "nocookiesfornew": "لم يتم إنشاء حساب المستخدم، لأننا لم نستطع تأكيد مصدره. \nتأكد من أن ملفات تعريف الارتباط (الكوكيز) مفعلة عندك، ثم أعد تحميل الصفحة وحاول مرة أخرى.",
+       "createacct-loginerror": "الحساب تم إنشاؤه تلقائيا لكن لم يمكن تسجيل دخولك تلقائيا. من فضلك اذهب إلى [[Special:UserLogin|تسجيل الدخول اليدوي]].",
        "noname": "لم تحدد اسم مستخدم صحيح.",
        "loginsuccesstitle": "تم الدخول",
        "loginsuccess": "'''لقد سجلت الدخول ل{{SITENAME}} باسم \"$1\".'''",
        "noemail": "لا يوجد عنوان بريد إلكتروني مسجل للمستخدم \"$1\".",
        "noemailcreate": "عليك تقديم عنوان بريد إلكتروني صالح",
        "passwordsent": "تم إرسال كلمة سر جديدة إلى عنوان البريد الإلكتروني المسجل للمستخدم \"$1\".\nمن فضلك حاول تسجيل الدخول مرة ثانية بعد استلامها.",
-       "blocked-mailpassword": "تم منع عنوان الأيبي الخاص بك من التحرير، ولمنع التخريب لا يمكنك أن تستخدم خاصية استرجاع كلمة السر.",
+       "blocked-mailpassword": "تم منع عنوان الأيبي الخاص بك من التحرير، ولمنع التخريب لا يمكنك أن تستخدم خاصية استرجاع كلمة السر من عنوان الآي بي هذا.",
        "eauthentsent": "تم إرسال رسالة تأكيد إلكترونية إلى العنوان المسمى.\nقبل إرسال أي رسالة أخرى لذلك الحساب، عليك أن تتبع التعليمات الواردة في الرسالة، لتأكيد أن هذا الحساب هو لك بالفعل.",
        "throttled-mailpassword": "تم بالفعل إرسال تذكير بكلمة السر، في ال{{PLURAL:$1||ساعة الماضية|ساعتين الماضيتين|$1 ساعات الماضية|$1 ساعة الماضية}}.\nلمنع التخريب، سيتم إرسال تذكير واحد كل {{PLURAL:$1||ساعة|ساعتين|$1 ساعات|$1 ساعة}}.",
        "mailerror": "خطأ أثناء إرسال البريد: $1",
        "changepassword-success": "تم تغيير كلمة السر !",
        "changepassword-throttled": "لديك محاولات تسجيل دخول كثيرة حديثة. من فضلك انتظر $1 قبل المحاولة ثانية.",
        "botpasswords": "كلمات مرور البوت",
+       "botpasswords-summary": "<em>كلمات سر البوت</em> يسمح بالوصول لحساب مستخدم من خلال API بدون استخدام اعتمادات تسجيل الدخول الرئيسية للحساب. صلاحيات المستخدم المتوفرة عند تسجيل الدخول باستخدام كلمة سر بوت ربما تكون مقيدة.\n\nلو أنك لا تعرف لماذا تريد فعل هذا، فأنت ينبغي على الأرجح ألا تففعله. لا أحد ينبغي أن يسألك أبدا أن تولد واحدة من هذه وإعطاؤهم إياها.",
        "botpasswords-disabled": "كلمات السر الخاصة بالبوت معطلة.",
        "botpasswords-no-central-id": "لاستخدام كلمة السر الخاصة بالبوت، يجب أن تقوم بتسجيل الدخول من خلال حساب موحد.",
        "botpasswords-existing": "كلمات مرور البوت الموجودة",
        "botpasswords-label-delete": "احذف",
        "botpasswords-label-resetpassword": "أعد ضبط كلمة السر",
        "botpasswords-label-grants": "المنح التي يمكن تطبيقها:",
+       "botpasswords-help-grants": "كل منحة تعطي وصولا لصلاحيات المستخدم المعروضة التي يمتلكها حساب المستخدم بالفعل. انظر [[Special:ListGrants|جدول المنح]] للمزيد من المعلومات.",
        "botpasswords-label-restrictions": "قيود الاستخدام:",
        "botpasswords-label-grants-column": "الممنوح",
        "botpasswords-bad-appid": "اسم البوت \"$1\" غير صحيح.",
        "botpasswords-insert-failed": "فشل في اضافة  اسم البوت \"$1\".هل اضيف بالفعل؟",
        "botpasswords-update-failed": "فشل في تحديث اسم بوت \"$1\". هل تم حذفه؟",
-       "botpasswords-created-title": "صÙ\86اعة Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø£Ù\84Ù\8aØ©",
-       "botpasswords-created-body": "تم إنشاء كلمة مرور بوت \"$1\".",
-       "botpasswords-updated-title": "تحديث كلمة السر الألية",
-       "botpasswords-updated-body": "كلمة سر البوت\"$1\" قد حذفت.",
+       "botpasswords-created-title": "تÙ\85 Ø¥Ù\86شاء Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø¨Ù\88ت",
+       "botpasswords-created-body": "تم إنشاء كلمة سر بوت \"$1\" للمستخدم \"$2\".",
+       "botpasswords-updated-title": "تم تحديث كلمة سر البوت",
+       "botpasswords-updated-body": "كلمة سر البوت \"$1\" للمستخدم \"$2\" تم تحديثها.",
        "botpasswords-deleted-title": "كلمة سر البوت حذفت",
-       "botpasswords-deleted-body": "كلمة سر البوت\"$1\" قد حذفت.",
+       "botpasswords-deleted-body": "كلمة سر البوت \"$1\" لمستخدم \"$2\" قد حذفت.",
+       "botpasswords-newpassword": "كلمة السر الجديدة لتسجيل الدخول ب <strong>$1</strong> هي <strong>$2</strong>. <em>من فضلك سجل هذه كمرجع في المستقبل .</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider غير متاح.",
        "botpasswords-restriction-failed": "قيود كلمة مرور البوت تمنع هذا الولوج.",
+       "botpasswords-invalid-name": "اسم المستخدم الموفر لا يحتوي على فاصل كلمة سر البوت (\"$1\").",
+       "botpasswords-not-exist": "المستخدم \"$1\" لا يمتلك كلمة سر بوت بالاسم \"$2\".",
        "resetpass_forbidden": "كلمات السر لا يمكن تغييرها",
        "resetpass_forbidden-reason": "لا يمكن تغيير كلمة المرور: $1",
        "resetpass-no-info": "يجب أن تكون مسجل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "passwordreset-emailelement": "اسم {{GENDER:$1\n|المستخدم|المستخدمة}}: \n$1\n\nكلمة السر المؤقتة: \n$2",
        "passwordreset-emailsentemail": "إذا كان هذا العنوان البريد مرتبط بحسابك، من ثم سيتم إرسال بريد إلكتروني لإعادة تعيين كلمة السر.",
        "passwordreset-emailsentusername": "إذا كان هناك عنوان بريد إلكتروني مرتبط بهذا المستخدم، ثم سيتم إرسال بريد إلكتروني لإعادة تعيين كلمة السر.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|رسالة|رسائل}} البريد الإلكتروني لضبط كلمة السر تم إرسالها. {{PLURAL:$1|اسم المستخدم وكلمة السر معروضان|قائمة أسماء المستخدمين وكلمات السر معروضة}} بالأسفل.",
+       "passwordreset-emailerror-capture2": "إرسال بريد إلى {{GENDER:$2|المستخدم|المستخدمة}} فشل: $1 {{PLURAL:$3|اسم المستخدم وكلمة السر معروضان|lقائمة أسماء المستخدمين كلمات السر معروضة}} بالأسفل.",
+       "passwordreset-nocaller": "يجب أن يتم توفير مستدعي",
+       "passwordreset-nosuchcaller": "المستدعي غير موجود: $1",
+       "passwordreset-ignored": "إعادة ضبط كلمة السر لم تتم التعامل معها. ربما لا موفر تم ضبطه؟",
        "passwordreset-invalideamil": "عنوان بريد إلكتروني غير صالح",
+       "passwordreset-nodata": "لا اسم مستخدم ولا عنوان بريد الإلكتروي تم توفيره",
        "changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
        "changeemail-header": "إكمال هذا النموذج لتغيير عنوان البريد الإلكتروني الخاص بك. إذا كنت ترغب في إزالة جمعية أي عنوان البريد الإلكتروني من حسابك، وترك الفراغ عنوان البريد الإلكتروني الجديد عند تقديم النموذج",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "changeemail-oldemail": "عنوان البريد الإلكتروني الحالي:",
        "changeemail-newemail": "عنوان البريد الإلكتروني الجديد:",
+       "changeemail-newemail-help": "هذا الحقل ينبغي أن يترك فارغا في حالة لو كنت تريد إزالة عنوان البريد الإلكتروني الخاص بك. أنت لن تكون قادرا على إعادة ضبط كلمة سر ضائعة ولن تتلقى رسئل بريد إلكتروني من هذه الويكي لو أزيل عنوان البريد الإلكتروني.",
        "changeemail-none": "(لا شيء)",
        "changeemail-password": "كلمة سر {{SITENAME}} الخاصة بك:",
        "changeemail-submit": "غيّر البريد الإلكتروني",
        "accmailtext": "أُرسِلت كلمة سر مولدة عشوائيا ل[[User talk:$1|$1]] إلى $2. يمكن تغييرها في صفحة ''[[Special:ChangePassword|تغيير كلمة السر]]'' بعد تسجيل الدخول.",
        "newarticle": "(جديد)",
        "newarticletext": "لقد تبعت وصلة لصفحة لم يتم إنشائها بعد.\nلإنشاء هذه الصفحة ابدأ الكتابة في الصندوق بالأسفل (انظر في [$1 صفحة المساعدة] للمزيد من المعلومات).\nإذا كانت زيارتك لهذه الصفحة بالخطأ، اضغط على زر ''رجوع'' في متصفح الإنترنت لديك.",
-       "anontalkpagetext": "----''هذه صفحة نقاش لمستخدم مجهول لم يقم بإنشاء حساب بعد أو لا يستعمل ذلك الحساب.\nلذا فيجب علينا استعمال رقم الأيبي للتعرف عليه/عليها.\nمثل هذا العنوان يمكن أن يشترك فيه عدة مستخدمين.\nلو كنت مستخدما مجهولا وتشعر بأن تعليقات لا تخصك تم توجيهها إليك، من فضلك [[Special:CreateAccount|أنشئ حسابا]] أو [[Special:UserLogin|سجل الدخول]] لتجنب الارتباك المستقبلي مع مستخدمين مجهولين آخرين.''",
+       "anontalkpagetext": "----\n<em>هذه صفحة نقاش لمستخدم مجهول لم يقم بإنشاء حساب بعد أو لا يستعمل ذلك الحساب.</em>\nلذا فيجب علينا استعمال رقم الأيبي للتعرف عليه/عليها.\nمثل هذا العنوان يمكن أن يشترك فيه عدة مستخدمين.\nلو كنت مستخدما مجهولا وتشعر بأن تعليقات لا تخصك تم توجيهها إليك، من فضلك [[Special:CreateAccount|أنشئ حسابا]] أو [[Special:UserLogin|سجل الدخول]] لتجنب الارتباك المستقبلي مع مستخدمين مجهولين آخرين.",
        "noarticletext": "الصفحة خالية. يمكنك [[Special:Search/{{PAGENAME}}|البحث عن عنوانها]] في الصفحات الأخرى أو\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} البحث في السجلات] (لتعرف إذا حذفت)،\nأو '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} إنشاؤها بنفسك]'''</span>.",
        "noarticletext-nopermission": "لا يوجد حاليا أي نص في هذه الصفحة.\nيمكنك [[Special:Search/{{PAGENAME}}|البحث عن عنوان هذه الصفحة]] في الصفحات الأخرى، أو <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} البحث في السجلات المتعلقة بها]</span>، لكنك لست مخولاً لإنشاء هذه الصفحة.",
        "missing-revision": "المراجعة #$1 من الصفحة المسماة \"{{FULLPAGENAME}}\" غير موجودة.\n\nهذا يحدث عادة عن طريق اتباع وصلة تاريخ قديمة لصفحة تم حذفها.\nالتفاصيل يمكن إيجادها في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
        "userpage-userdoesnotexist": "حساب المستخدم \"<nowiki>$1</nowiki>\" غير مسجل.\nمن فضلك تأكد أنك تريد إنشاء/تعديل هذه الصفحة.",
        "userpage-userdoesnotexist-view": "حساب المستخدم \"$1\" غير مسجل.",
        "blocked-notice-logextract": "هذا المستخدم ممنوع حاليا.\nآخر مدخلة في سجل المنع موفرة بالأسفل كمرجع:",
-       "clearyourcache": "'''ملاحظة:''' بعد الحفظ، قد تحتاج إلى إفراغ كاش متصفحك لرؤية التغييرات.\n* '''فايرفوكس / سفاري:''' اضغط ''Shift'' أثناء ضغط ''Reload''، أو اضغط أيا من ''Ctrl-F5'' أو ''Ctrl-R'' (''⌘-R'' على ماك)\n* '''جوجل كروم:''' اضغط ''Ctrl-Shift-R'' (''⌘-Shift-R'' على ماك)\n* '''إنترنت إكسبلورر:''' اضغط ''Ctrl'' أثناء ضغط ''Refresh''، أو اضغط ''Ctrl-F5''\n* '''كنكرر:''' اضغط ''Reload'' أو اضغط ''F5''\n* '''أوبرا:''' أفرغ الكاش في ''Tools → Preferences''",
+       "clearyourcache": "<strong>ملاحظة:</strong> بعد الحفظ، أنت قد تحتاج إلى إفراغ الكاش الخاص بمتصفحك لرؤية التغييرات.\n* <strong>فايرفوكس / سافاري:</strong> أمسك <em>Shift</em> أثناء ضغط <em>Reload</em>، أو اضغط على إما <em>Ctrl-F5</em> أو <em>Ctrl-R</em> (<em>⌘-R</em> على ماك)\n* <strong>جوجل كروم:</strong> اضغط <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> على ماك)\n* <strong>إنترنت إكسبلورر:</strong> أمسك <em>Ctrl</em> أثناء ضغط <em>Refresh</em>، أو اضغط <em>Ctrl-F5</em>\n* <strong>أوبرا:</strong> اذهب إلى <em>Menu → Settings</em> (<em>Opera → Preferences</em> على ماك) ثم إلى <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''ملاحظة:''' استعمل زر \"{{int:showpreview}}\" لتجربة CSS الجديد قبل حفظ الصفحة.",
        "userjsyoucanpreview": "'''ملاحظة:''' استعمل زر \"{{int:showpreview}}\" لتجربة جافاسكربت الجديدة قبل حفظ الصفحة.",
        "usercsspreview": "'''تذكر أنك تقوم بعرض الأنماط المتراصة (CSS) الخاصة بك فقط\nلم يتم حفظها بعد!'''",
        "permissionserrors": "خطأ في السماح",
        "permissionserrorstext": "لا تمتلك الصلاحية لفعل هذا، {{PLURAL:$1||للسبب التالي|للسببين التاليين|للأسباب التالية}}:",
        "permissionserrorstext-withaction": "لا تملك الصلاحيات ل$2، لل{{PLURAL:$1||سبب التالي|سببين التاليين|أسباب التالية}}:",
+       "contentmodelediterror": "أنت لا يمكنك تعديل هذه المراجعة لأن موديل محتواها هو  <code>$1</code>، والذي يختلف عن موديل المحتوى الحالي للصفحة  <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''تحذير: أنت تعيد إنشاء صفحة سبق حذفها.'''\n\nيجب عليك التيقن من أن الاستمرار بتحرير هذه الصفحة ملائم.\nسجلا الحذف والنقل لهذه الصفحة معروضان هنا للتيسير:",
        "moveddeleted-notice": "هذه الصفحة تم حذفها.\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
+       "moveddeleted-notice-recent": "عذرا، هذه الصفحة تم حذفها مؤخرا (في آخر 24 ساعة).\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
        "log-fulllog": "أظهر السجل الكامل",
        "edit-hook-aborted": "التعديل تم تركه بواسطة الخطاف.\nلم يعط تفسيرا.",
        "edit-gone-missing": "لم يمكن تحديث الصفحة.\nيبدو أنه تم حذفها.",
        "content-model-text": "نص عادي",
        "content-model-javascript": "جافاسكربت",
        "content-model-css": "CSS",
-       "content-json-empty-object": "غرض فارغ",
+       "content-json-empty-object": "كائن فارغ",
        "content-json-empty-array": "مصفوفة فارغة",
        "deprecated-self-close-category": "صفحات تستخدم وسوم أتش تي أم أل غير صالحة",
+       "deprecated-self-close-category-desc": "هذه الصفحة تحتوي على وسوم HTML مغلقة ذاتيا، مثل  <code>&lt;b/></code> أو <code>&lt;span/></code>. سلوك هذه سيتغير سريعا ليكون متوافقا مع معيار HTML5، لذا فاستخدامهم في نص الويكي ينبغي أن يتم الاستغناء عنه.",
        "duplicate-args-warning": "<strong>تنبيه:</strong> المدخل \"$3\" ل[[:$1]] المستعمل في [[:$2]] مكرر. آخر قيمة مكرر منه هي المعتمدة.",
        "duplicate-args-category": "صفحات تستعمل قالبا ببيانات مكررة",
        "duplicate-args-category-desc": "تحوي هذه الصفحة استدعاءات قالب تستخدم متغيرات مزدوجة مثل <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> أو <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "revdel-restore": "تغيير الرؤية",
        "pagehist": "تاريخ الصفحة",
        "deletedhist": "التاريخ المحذوف",
-       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø­فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
+       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø®فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
        "revdelete-show-no-access": "خطأ في إظهار العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-no-access": "خطأ في تعديل العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-missing": "خطأ في تعديل العنصر ذا الهوية $1: العنصر مفقود من قاعدة البيانات!",
        "mergehistory-go": "عرض التعديلات القابلة للدمج",
        "mergehistory-submit": "دمج المراجعات",
        "mergehistory-empty": "لا مراجعات يمكن دمجها.",
-       "mergehistory-done": "$3 {{PLURAL:$3|مراجعة|مراجعة}} من $1{{PLURAL:$3|كان|اين}} تم دمجها بنجاح في [[:$2]].",
+       "mergehistory-done": "$3 {{PLURAL:$3|مراجعة}} من $1{{PLURAL:$3|كان|اين}} تم دمجها بنجاح في [[:$2]].",
        "mergehistory-fail": "غير قادر على عمل دمج التاريخ، من فضلك أعد التحقق من محددات الصفحة والزمن.",
        "mergehistory-fail-bad-timestamp": "الختم الزمني غير صالح.",
        "mergehistory-fail-invalid-source": "الصفحة المصدر غير صالحة.",
        "localtime": "الوقت المحلي:",
        "timezoneuseserverdefault": "استخدام الويكي الافتراضي ($1)",
        "timezoneuseoffset": "آخر (حدد الفرق)",
-       "servertime": "Ù\88Ù\82ت Ø§Ù\84خادÙ\88Ù\85:",
+       "servertime": "وقت الخادم:",
        "guesstimezone": "أدخل التوقيت من المتصفح",
        "timezoneregion-africa": "أفريقيا",
        "timezoneregion-america": "أمريكا",
        "prefs-files": "ملفات",
        "prefs-custom-css": "CSS مخصص",
        "prefs-custom-js": "جافاسكربت مخصص",
-       "prefs-common-css-js": "سي إس إس وجافاسكربت مشترك لجميع المظاهر:",
+       "prefs-common-css-js": "CSS وجافاسكربت مشترك لجميع الواجهات:",
        "prefs-reset-intro": "يمكنك استخدام هذه الصفحة لإعادة تفضيلاتك للحالة الافتراضية للموقع.\nلن تستطيع استرجاع الحالة السابقة.",
        "prefs-emailconfirm-label": "تأكيد البريد الإلكتروني:",
        "youremail": "البريد:",
        "userrights-removed-self": "أزلت بنجاح صلاحياتك، ولن تتمكن من الوصول لهذه الصفحة مجددا.",
        "group": "المجموعة:",
        "group-user": "مستخدمون",
-       "group-autoconfirmed": "مستخدمون مؤكدون تلقائياً",
+       "group-autoconfirmed": "مستخدمون مؤكدون تلقائيا",
        "group-bot": "بوتات",
-       "group-sysop": "مديرو نظام",
+       "group-sysop": "إداريون",
        "group-bureaucrat": "بيروقراطيون",
        "group-suppress": "مزيلون",
        "group-all": "(الكل)",
        "group-bureaucrat-member": "{{GENDER:$1|بيروقراط}}",
        "group-suppress-member": "{{GENDER:$1|مزيل|مزيلة}}",
        "grouppage-user": "{{ns:project}}:مستخدمون",
-       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائياً",
+       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائيا",
        "grouppage-bot": "{{ns:project}}:بوتات",
        "grouppage-sysop": "{{ns:project}}:إداريون",
        "grouppage-bureaucrat": "{{ns:project}}:بيروقراطيون",
        "right-move": "نقل الصفحات",
        "right-move-subpages": "نقل الصفحات مع صفحاتها الفرعية",
        "right-move-rootuserpages": "نقل صفحات المستخدمين الأساسية",
-       "right-move-categorypages": "انقل صفحات التصنيف",
+       "right-move-categorypages": "نقل صفحات التصنيف",
        "right-movefile": "نقل الملفات",
        "right-suppressredirect": "عدم إنشاء تحويلة من الاسم القديم عند نقل صفحة",
        "right-upload": "رفع الملفات",
        "right-writeapi": "استخدام API للكتابة",
        "right-delete": "حذف الصفحات",
        "right-bigdelete": "حذف الصفحات ذات التواريخ الكبيرة",
-       "right-deletelogentry": "حذÙ\81 Ù\88اÙ\84غاء Ø­Ø°Ù\81 Ø¥Ø¯Ø®Ø§Ù\84ات Ø³Ø¬Ù\84 Ù\85عÙ\8aÙ\86",
+       "right-deletelogentry": "حذÙ\81 Ù\88Ø¥Ù\84غاء Ø­Ø°Ù\81 Ù\85دخÙ\84ات Ø³Ø¬Ù\84 Ù\85عÙ\8aÙ\86Ø©",
        "right-deleterevision": "حذف واسترجاع مراجعات معينة من الصفحات",
        "right-deletedhistory": "رؤية مدخلات التاريخ المحذوفة، بدون نصوصها المصاحبة",
        "right-deletedtext": "عرض النص المحذوف والتغييرات بين المراجعات المحذوفة",
        "right-browsearchive": "البحث في الصفحات المحذوفة",
        "right-undelete": "استرجاع صفحة",
        "right-suppressrevision": "مراجعة واسترجاع المراجعات المخفية عن مديري النظام",
-       "right-viewsuppressed": "أعرض Ø§Ù\84Ù\85راجعات Ø§Ù\84Ù\85Ø®Ù\81Ù\8aØ© Ø¨Ù\88اسطة Ø£Ù\8a Ù\85ستخدÙ\85",
+       "right-viewsuppressed": "عرض المراجعات المخفية بواسطة أي مستخدم",
        "right-suppressionlog": "رؤية السجلات السرية",
        "right-block": "منع المستخدمين الآخرين من التعديل",
        "right-blockemail": "منع مستخدم من إرسال بريد إلكتروني",
        "right-editinterface": "تعديل واجهة المستخدم",
        "right-editusercssjs": "تعديل ملفات CSS و JS للمستخدمين الآخرين",
        "right-editusercss": "تعديل ملفات CSS للمستخدمين الآخرين",
-       "right-edituserjs": "تعديل ملفات JS للمستخدمين الآخرين",
+       "right-edituserjs": "تعديل ملفات جافاسكريبت للمستخدمين الآخرين",
        "right-editmyusercss": "تعديل ملفات CSS للمستخدم نفسه",
        "right-editmyuserjs": "تعديل ملفات جافاسكربت للمستخدم نفسه",
        "right-viewmywatchlist": "عرض قائمة مراقبتك",
        "right-editmywatchlist": "حرر قائمة مراقبتك. لاحظ أن بعض الإجراءات لا تزال تضيف الصفحات حتى بدون هذا الحق.",
-       "right-viewmyprivateinfo": "إستعرض Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84Ø¥سم الحقيقي)",
-       "right-editmyprivateinfo": "حرر Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84Ø¥سم الحقيقي)",
+       "right-viewmyprivateinfo": "استعراض Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84اسم الحقيقي)",
+       "right-editmyprivateinfo": "تعدÙ\8aÙ\84 Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84اسم الحقيقي)",
        "right-editmyoptions": "تعديل تفضيلاتك",
        "right-rollback": "استرجاع تعديلات آخر مستخدم عدل صفحة معينة سريعا",
        "right-markbotedits": "التعليم على تعديلات الاسترجاع كتعديلات بوت",
        "right-import": "استيراد الصفحات من ويكيات أخرى",
        "right-importupload": "استيراد الصفحات من ملف مرفوع",
        "right-patrol": "تعليم تعديلات الآخرين بعلامة المراجعة",
-       "right-autopatrol": "عÙ\84Ù\85 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84Ù\85ستخدÙ\85 مراجعة تلقائيا",
+       "right-autopatrol": "اÙ\84تعÙ\84Ù\8aÙ\85 Ø¹Ù\84Ù\89 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84Ù\85ستخدÙ\85 Ù\83مراجعة تلقائيا",
        "right-patrolmarks": "رؤية علامات المراجعة في أحدث التغييرات",
        "right-unwatchedpages": "رؤية قائمة بالصفحات غير المراقبة",
        "right-mergehistory": "دمج تاريخ الصفحات",
        "right-override-export-depth": "تصدير الصفحات متضمنة الصفحات الموصولة حتى عمق 5",
        "right-sendemail": "إرسال رسائل بريد إلكتروني إلى مستخدمين آخرين",
        "right-passwordreset": "عرض رسائل إعادة ضبط كلمات السر",
-       "right-managechangetags": "Ø¥Ù\86شاء Ù\88حذÙ\81 [[Special:Tags|اÙ\84Ù\88سÙ\88Ù\85]] Ù\85Ù\86 Ù\82اعدة Ø§Ù\84بÙ\8aاÙ\86ات",
+       "right-managechangetags": "Ø¥Ù\86شاء Ù\88تعطÙ\8aÙ\84 [[Special:Tags|اÙ\84Ù\88سÙ\88Ù\85]]",
        "right-applychangetags": "تطبيق [[Special:Tags|الوسوم]]  مع التغييرات التي أجريتها.",
+       "right-changetags": "إضافة وإزالة [[Special:Tags|وسوم]] في مراجعات ومدخلات سجل فردية",
+       "right-deletechangetags": "حذف [[Special:Tags|الوسوم]] من قاعدة البيانات",
        "grant-generic": "\"$1\" حزمة الصلاحيات",
        "grant-group-page-interaction": "التفاعل مع الصفحات",
        "grant-group-file-interaction": "التفاعل مع الوسائط",
        "grant-group-high-volume": "أداء نشاط كبير الحجم",
        "grant-group-customization": "التخصيص والتفضيلات",
        "grant-group-administration": "أداء عمليات إدارية",
+       "grant-group-private-information": "الوصول للبيانات السرية المتعلقة بك",
        "grant-group-other": "نشاطات متفرقة",
        "grant-blockusers": "منع ورفع المنع عن المستخدمين",
        "grant-createaccount": "إنشاء حسابات",
        "grant-createeditmovepage": "إنشاء وتعديل ونقل الصفحات",
        "grant-delete": "حذف الصفحات والمراجعات ومدخلات السجلات",
+       "grant-editinterface": "تعديل نطاق ميدياويكي والCSS/JavaScript الخاصة بالمستخدم",
+       "grant-editmycssjs": "تعديل الCSS/JavaScript الخاصة بحسابك",
        "grant-editmyoptions": "تعديل تفضيلاتك",
        "grant-editmywatchlist": "تعديل قائمة مراقبتك",
        "grant-editpage": "تعديل صفحات موجودة",
        "grant-editprotected": "تعديل صفحات محمية",
        "grant-highvolume": "تعديل كبير الحجم",
+       "grant-oversight": "إخفاء المستخدمين وإخفاء المراجعات",
        "grant-patrol": "تغييرات دورية للصفحات",
+       "grant-privateinfo": "الوصول للمعلومات السرية",
        "grant-protect": "حماية وإزالة حماية الصفحات",
        "grant-rollback": "استرجاع التغييرات في الصفحات",
        "grant-sendemail": "إرسال بريد إلكتروني للمستخدمين الآخرين",
        "action-read": "قراءة هذه الصفحة",
        "action-edit": "تعديل هذه الصفحة",
        "action-createpage": "إنشاء هذه الصفحة",
-       "action-createtalk": "Ø¥Ù\86شاء ØµÙ\81حات Ø§Ù\84Ù\86Ù\82اش",
+       "action-createtalk": "Ø¥Ù\86شاء ØµÙ\81حة Ø§Ù\84Ù\86Ù\82اش Ù\87Ø°Ù\87",
        "action-createaccount": "إنشاء حساب المستخدم هذا",
-       "action-autocreateaccount": "تلقائيا إنشاء هذا الحساب مستخدم خارجي",
+       "action-autocreateaccount": "تلقائيا إنشاء هذا الحساب الخارجي للمستخدم",
        "action-history": "اعرض تاريخ هذه الصفحة",
        "action-minoredit": "التعليم على هذا التعديل كطفيف",
        "action-move": "نقل هذه الصفحة",
        "action-viewmyprivateinfo": "مشاهدة معلوماتك الخاصة",
        "action-editmyprivateinfo": "تعديل معلوماتك الخاصة",
        "action-editcontentmodel": "عدل عدل طريقة محتوى صفحة",
-       "action-managechangetags": "Ø¥Ù\86شاء Ù\88حذÙ\81 Ø§Ù\84Ù\88سÙ\88Ù\85 Ù\85Ù\86 Ù\82اعدة Ø§Ù\84بÙ\8aاÙ\86ات",
+       "action-managechangetags": "Ø¥Ù\86شاء Ù\88تعطÙ\8aÙ\84 Ø§Ù\84Ù\88سÙ\88Ù\85",
        "action-applychangetags": "تطبيق الوسوم مع تغييراتك",
+       "action-changetags": "أضف وأزل وسوما في مراجعات ومدخلات سجل فردية",
+       "action-deletechangetags": "حذف الوسوم من قاعدة البيانات",
+       "action-purge": "إفراغ كاش هذه الصفحة",
        "nchanges": "{{PLURAL:$1|لا تغييرات|تغيير واحد|تغييران|$1 تغييرات|$1 تغييرا|$1 تغيير}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|منذ الزيارة الأخيرة}}",
        "enhancedrc-history": "تاريخ",
        "recentchangeslinked-page": "اسم الصفحة:",
        "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
        "recentchanges-page-added-to-category": "[[:$1]] أضيفت إلى التصنيف",
-       "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] و{{PLURAL:$2|صفحة واحدة|صفحتان|$2 صفحات}} إلى التصنيف",
+       "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] إلى التصنيف، [[Special:WhatLinksHere/$1|هذه الصفحة مضمنة في صفحات اخرى]]",
        "recentchanges-page-removed-from-category": "أزيلت [[:$1]] من التصنيف",
-       "recentchanges-page-removed-from-category-bundled": "أزÙ\8aÙ\84ت [[:$1]] Ù\88{{PLURAL:$2|صÙ\81حة Ù\88احدة|صÙ\81حتاÙ\86|$2 ØµÙ\81حات}} Ù\85Ù\86 Ø§Ù\84تصÙ\86Ù\8aÙ\81",
+       "recentchanges-page-removed-from-category-bundled": "أزÙ\8aÙ\84ت [[:$1]] Ù\85Ù\86 Ø§Ù\84تصÙ\86Ù\8aÙ\81Ø\8c [[Special:WhatLinksHere/$1|Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة Ù\85ضÙ\85Ù\86Ø© Ù\81Ù\8a ØµÙ\81حات Ø£Ø®Ø±Ù\89]]",
        "autochange-username": "تغيير آلي لميدياويكي",
        "upload": "ارفع ملفا",
        "uploadbtn": "ارفع الملف",
        "uploaddisabledtext": "رفع الملفات معطل.",
        "php-uploaddisabledtext": "رفع ملفات PHP معطل. من فضلك تحقق من إعدادات رفع الملفات.",
        "uploadscripted": "هذا الملف يضم كود HTML أو كود آخر يمكن أن يفسره متصفح الوب بطريقة خاطئة.",
+       "upload-scripted-pi-callback": "لا يمكن رفع ملف يحتوي على تعليمة معالجة XML-stylesheet",
+       "uploaded-script-svg": "تم العثور على عنصر سكريبت \"$1\" في ملف الSVG المرفوع.",
+       "uploaded-hostile-svg": "تم العثور على CSS غير آمن في عنصر الشكل في ملف الSVG المرفوع.",
+       "uploaded-event-handler-on-svg": "ضبط سمات معالج الأحداث <code>$1=\"$2\"</code> غير مسموح به في ملفات SVG.",
+       "uploaded-href-attribute-svg": "سمات href في ملفات SVG مسموح بوصلها فقط بأهداف http:// أو https:// ، تم العثور على <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "تم العثور على href لبيانات غير آمنة: هدف URI <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-animate-svg": "تم العثور على وسم \"animate\" الذي ربما يكون يغير href, باستخدام سمة \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-event-handler-svg": "ضبط سمات معالج الأحداث ممنوع، تم العثور على <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-href-svg": "استخدام وسم \"set\" لإضافة سمة \"href\" للعنصر الأب ممنوع.",
+       "uploaded-wrong-setting-svg": "استخدام وسم \"set\" لإضافة هدف خارجي/بيانات/سكريبت لأي سمة ممنوع. تم العثور على <code>&lt;set to=\"$1\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-handler-svg": "SVG الذي يضبط سمة \"handler\" مع خارجي/بيانات/سكريبت ممنوع. تم العثور على <code>$1=\"$2\"</code> في ملف SVG المرفوع.",
+       "uploaded-remote-url-svg": "SVG الذي يضبط أي سمة شكل مع URL خارجي ممنوع. تم العثور على <code>$1=\"$2\"</code> في ملف SVG المرفوع.",
+       "uploaded-image-filter-svg": "تم العثور على فلتر صورة مع URL: <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
        "uploadscriptednamespace": "يحتوي ملف SVG هذا على اسم نطاق غير مشروع \" $1 \"",
        "uploadinvalidxml": "تعذر تحليل XML في الملف المرفوع.",
        "uploadvirus": "الملف يحتوي على فيروس! التفاصيل: $1",
        "upload-options": "خيارات الرفع",
        "watchthisupload": "راقب هذا الملف",
        "filewasdeleted": "تم رفع ثم حذف ملف بهذا الاسم من قبل.\nمن الأفضل مراجعة $1 قبل رفعه مرة أخرى.",
+       "filename-thumb-name": "هذا يبدو وكأنه عنوان صورة مصغرة. من فضلك لا ترفع صورة مصغرة لنفس الويكي مرة ثانية. أو، من فضلك أصلح اسم الملف بحيث يكون معبرا أكثر، ولا يحتوي على بادئة الصورة المصغرة.",
        "filename-bad-prefix": "اسم الملف الذي ترفعه يبدأ ب'''\"$1\"'''، وهو اسم غير وصفي غالباً ما تخصصه الكاميرات الرقمية تلقائياً.\nمن فضلك اختر اسماً يصف ملفك بوضوح أكثر.",
        "filename-prefix-blacklist": " #<!-- اترك هذا السطر تماما كما هو --> <pre>\n# الصيغة كالتالي:\n#   * كل شيء من علامة \"#\" إلى آخر السطر هو تعليق\n#   * كل سطر غير فارغ هو بادئة لأسماء الملفات النمطية التي توضع تلقائيا بواسطة الكاميرات الرقمية\nCIMG # كاسيو\nDSC_ # نيكون\nDSCF # فوجي\nDSCN # نيكون\nDUW # بعض الهواتف المحمولة\nIMG # عام\nJD # جينوبتيك\nMGP # بينتاكس\nPICT # متنوع\n #</pre> <!-- اترك هذا السطر تماما كما هو -->",
        "upload-proto-error": "بروتوكول غير صحيح",
        "upload-too-many-redirects": "احتوى المسار تحويلات كثيرة جدا",
        "upload-http-error": "صودف خطأ HTTP: $1",
        "upload-copy-upload-invalid-domain": "رفع النسخ غير متاح من هذا الموقع",
+       "upload-foreign-cant-upload": "هذه الويكي ليست مضبوطة لرفع الملفات لمستودع الملفات الخارجي المطلوب.",
+       "upload-foreign-cant-load-config": "فشل تحميل الإعدادات للملفات المرفوعة لمستودع الملفات الخارجي.",
+       "upload-dialog-disabled": "رفع الملفات باستخدام هذا الحوار معطلة على هذه الويكي.",
        "upload-dialog-title": "رفع الملف",
        "upload-dialog-button-cancel": "إلغاء",
        "upload-dialog-button-done": "تم",
        "upload-dialog-button-upload": "رفع",
        "upload-form-label-infoform-title": "التفاصيل",
        "upload-form-label-infoform-name": "الاسم",
+       "upload-form-label-infoform-name-tooltip": "عنوان وصفي فريد للملف، والذي سيكون اسم الملف. يمكنك أن تستخدم لغة عادية مع مسافات. لا تضمن امتداد الملف.",
        "upload-form-label-infoform-description": "الوصف",
+       "upload-form-label-infoform-description-tooltip": "باختصار صف كل شيء ملحوظ حول العمل.\nلصورة، اذكر الأشياء الأساسية المصورة، المناسبة أو المكان.",
        "upload-form-label-usage-title": "الاستخدام",
        "upload-form-label-usage-filename": "اسم الملف",
        "upload-form-label-own-work": "هذا عملي الخاص",
        "upload-form-label-infoform-categories": "تصنيفات",
        "upload-form-label-infoform-date": "التاريخ",
+       "upload-form-label-own-work-message-generic-local": "أنا أؤكد أنني أقوم برفع هذا الملف مع مراعاة شروط الخدمة وسياسات الترخيص في {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "لو أنك غير قادر على رفع هذا الملف تحت سياسات {{SITENAME}}، من فضلك أغلق هذا الحوار وجرب طريقة أخرى.",
+       "upload-form-label-not-own-work-local-generic-local": "أنت ربما تريد تجربة [[Special:Upload|صفحة الرفع الافتراضية]].",
+       "upload-form-label-own-work-message-generic-foreign": "أنا أفهم أنني أقوم برفع هذا الملف إلى مستودع مشترك. أنا أؤكد أنني أقوم بهذا بالتوافق مع شروط الخدمة وسياسات الترخيص هناك.",
+       "upload-form-label-not-own-work-message-generic-foreign": "لو أنك غير قادر على رفع هذا الملف تحت سياسات المستودع المشترك، من فضلك أغلق هذا الحوار وجرب طريقة أخرى.",
+       "upload-form-label-not-own-work-local-generic-foreign": "أنت ربما تريد أيضا تجربة [[Special:Upload|صفحة الرفع على {{SITENAME}}]]، لو أن هذا الملف يمكن رفعه هناك تحت سياساتهم.",
        "backend-fail-stream": "لا يمكن عرض الملف $1.",
        "backend-fail-backup": "لا يمكن صنع نسخة أحتياطية للملف $1.",
        "backend-fail-notexists": "الملف $1 غير موجود.",
-       "backend-fail-hashes": "لم يمكن الحصول على هاش الملف من أجل المقارنة",
-       "backend-fail-notsame": "يوجد بالفعل ملف غير متطابق في $1.",
-       "backend-fail-invalidpath": "$1 ليس مساراً صالحاً للتخزين.",
-       "backend-fail-delete": "لم يمكن حذف الملف $1.",
-       "backend-fail-describe": "Ù\84ا Ù\8aÙ\85Ù\83Ù\86 ØªØºÙ\8aÙ\8aر Ø§Ù\84بÙ\8aاÙ\86ات Ø§Ù\84تعرÙ\8aÙ\81 (metadata) Ù\84Ù\84Ù\85Ù\84Ù\81 \" $1 \".",
-       "backend-fail-alreadyexists": "الملف $1 موجود بالفعل.",
-       "backend-fail-store": "لا يمكن تخزين الملف $1 في $2 .",
-       "backend-fail-copy": "لا يمكن نسخ الملف  $1  إلى  $2 .",
-       "backend-fail-move": "تعذر نقل ملف $1 إلى $2 .",
+       "backend-fail-hashes": "لم يمكن الحصول على hashes الملفات من أجل المقارنة",
+       "backend-fail-notsame": "يوجد بالفعل ملف غير متطابق في \"$1\".",
+       "backend-fail-invalidpath": "\"$1\" ليس مساراً صالحاً للتخزين.",
+       "backend-fail-delete": "لم يمكن حذف الملف \"$1\".",
+       "backend-fail-describe": "Ù\84ا Ù\8aÙ\85Ù\83Ù\86 ØªØºÙ\8aÙ\8aر Ø¨Ù\8aاÙ\86ات Ø§Ù\84تعرÙ\8aÙ\81 metadata Ù\84Ù\84Ù\85Ù\84Ù\81 \"$1\".",
+       "backend-fail-alreadyexists": "الملف \"$1\" موجود بالفعل.",
+       "backend-fail-store": "لا يمكن تخزين الملف \"$1\" في \"$2\".",
+       "backend-fail-copy": "لا يمكن نسخ الملف  \"$1\"  إلى  \"$2\".",
+       "backend-fail-move": "تعذر نقل ملف \"$1\" إلى \"$2\".",
        "backend-fail-opentemp": "تعذّر فتح ملف مؤقت.",
        "backend-fail-writetemp": "تعذّرت كتابة ملف مؤقت.",
        "backend-fail-closetemp": "تعذّر إغلاق ملف مؤقت.",
        "backend-fail-read": "لا يمكن قراءة الملف $1.",
        "backend-fail-create": "تعذر كتابة الملف $1.",
        "backend-fail-maxsize": "تعذر كتابة الملف $1 لأنه أكبر من  {{PLURAL:$2|بايت واحد|$2 بايت}}.",
-       "backend-fail-readonly": "خلفية التخزين \"$1\" في وضعية القراءة فقط حاليا. السبب في ذلك هو: \"$2\"",
+       "backend-fail-readonly": "خلفية التخزين \"$1\" في وضعية القراءة فقط حاليا. السبب في ذلك هو:\n<em>$2</em>",
        "backend-fail-synced": "الملف \"$1\" في حالة غير متناسقة ضمن خلفية التخزين الداخلية",
        "backend-fail-connect": "تعذر ربط الإتصال بخلفية التخزين \"$1\".",
        "backend-fail-internal": "وقع خطأ غير معروف في خلفية التخزين \"$1\".",
        "uploadstash-summary": " توفر هذه الصفحة الوصول إلى الملفات التي يتم تحميلها (أو في أثناء عملية التحميل) ولكنها لم تنشر بعد. هذه الملفات هي غير مرئية لأحد إلا للمستخدم الذين تم الرفع لهم.",
        "uploadstash-clear": "مسح الملفات المخبأة",
        "uploadstash-nofiles": "ليس لديك أي ملفات مخبأة.",
-       "uploadstash-badtoken": "Ù\84Ù\85 Ù\8aÙ\86جح Ø£Ø¯Ø§Ø¡ Ø°Ù\84Ù\83 Ø§Ù\84عÙ\85Ù\84Ø\8c Ø±Ø¨Ù\85ا Ù\84Ø£Ù\86 Ù\88ثائÙ\82 ØªÙ\81Ù\88Ù\8aض Ø§Ù\84تحرÙ\8aر Ø§Ù\84خاصة Ø¨Ù\83 Ù\85Ù\86تÙ\87Ù\8aØ© Ø§Ù\84صÙ\84احÙ\8aØ©. حاول مرة أخرى.",
+       "uploadstash-badtoken": "Ù\81Ø´Ù\84 Ø£Ø¯Ø§Ø¡ Ø°Ù\84Ù\83 Ø§Ù\84عÙ\85Ù\84Ø\8c Ø±Ø¨Ù\85ا Ù\84Ø£Ù\86 Ù\88ثائÙ\82 ØªÙ\81Ù\88Ù\8aض Ø§Ù\84تحرÙ\8aر Ø§Ù\84خاصة Ø¨Ù\83 Ù\85Ù\86تÙ\87Ù\8aØ© Ø§Ù\84صÙ\84احÙ\8aØ©. Ù\85Ù\86 Ù\81ضÙ\84Ù\83 حاول مرة أخرى.",
        "uploadstash-errclear": "فشلت عملية مسح الملفات.",
        "uploadstash-refresh": "تحديث قائمة الملفات",
        "uploadstash-thumbnail": "اعرض صورة مصغرة",
+       "uploadstash-exception": "لم يمكن تخزين الرفع في الstash ($1): \"$2\".",
        "invalid-chunk-offset": "قطعة أوفست غير صالحة",
        "img-auth-accessdenied": "رفض الوصول",
        "img-auth-nopathinfo": "PATH_INFO مفقود.\nخادومك ليس مضبوطاً لتمرير هذه المعلومة.\nقد يكون مبنياً على نظام CGI ولا يمكنه دعم img_auth.\nراجع https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "apisandbox": "ملعب API",
        "apisandbox-jsonly": "الجافا سكريبت مطلوبة لاستخدام ملعب API",
        "apisandbox-api-disabled": "واجهة برمجة التطبيق API معطلة في هذا الموقع.",
+       "apisandbox-intro": "استخدم هذه الصفحة للتجربة ب<strong>MediaWiki web service API</strong>.\nارجع إلى [[mw:API:Main page|توثيق الAPI]] للمزيد من التفاصيل حول استخدام الAPI. مثال: [https://www.mediawiki.org/wiki/API#A_simple_example احصل على محتوى صفحة رئيسية]. اختر فعلا لترى المزيد من الأمثلة.\n\nلاحظ أنه، على الرغم من أن هذا ملعب، فالأفعال التي تقوم بها على هذه الصفحة ربما تعدل الويكي.",
        "apisandbox-fullscreen": "وسع اللوحة",
+       "apisandbox-fullscreen-tooltip": "وسع صفحة الملعب لتملأ نافذة المتصفح.",
        "apisandbox-unfullscreen": "أظهر الصفحة",
+       "apisandbox-unfullscreen-tooltip": "قلل صفحة الملعب، حتى تكون وصلات التصفح لميدياويكي متوفرة.",
        "apisandbox-submit": "عمل الطلب",
        "apisandbox-reset": "إفراغ",
        "apisandbox-retry": "أعد المحاولة",
+       "apisandbox-loading": "تحميل المعلومات لAPI module \"$1\"...",
+       "apisandbox-load-error": "حدث خطأ أثناء تحميل المعلومات لAPI module \"$1\": $2",
        "apisandbox-no-parameters": "وحدة API هذه ليس بها معاملات.",
        "apisandbox-helpurls": "وصلات المساعدة",
        "apisandbox-examples": "أمثلة",
        "apisandbox-dynamic-parameters-add-placeholder": "اسم المعامل",
        "apisandbox-dynamic-error-exists": "يوجد بالفعل معامل باسم \"$1\".",
        "apisandbox-deprecated-parameters": "معاملات مهملة",
+       "apisandbox-fetch-token": "املأ التوكين تلقائيا",
        "apisandbox-submit-invalid-fields-title": "بعض الحقول غير صالحة",
        "apisandbox-submit-invalid-fields-message": "برجاء تصحيح الحقل المعلم والمحاولة مرة أخرى.",
        "apisandbox-results": "النتائج",
        "apisandbox-sending-request": "إرسال طلب API ...",
        "apisandbox-loading-results": "استقبال طلبات API ...",
+       "apisandbox-results-error": "حدث خطأ أثناء تحميل رد استعدلام الAPI: $1.",
        "apisandbox-request-url-label": "مسار الطلب:",
        "apisandbox-request-time": "وقت الطلب: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "رمز الصحيح وإعادة الموافقة",
+       "apisandbox-results-fixtoken-fail": "فشل جلب توكين \"$1\"",
        "apisandbox-alert-page": "هناك حقول غير صالحة في هذه الصفحة.",
        "apisandbox-alert-field": "قيمة هذا الحقل غير صالحة.",
        "booksources": "مصادر كتاب",
        "booksources-text": "توجد أدناه قائمة بوصلات لمواقع أخرى تبيع الكتب الجديدة والمستعملة، أيضا يمكنك أن تحصل على معلومات إضافية عن الكتب التي تبحث عنها من هناك:",
        "booksources-invalid-isbn": "رقم ISBN المعطى لا يبدو صحيحا؛ تحقق من أخطاء النسخ من المصدر الأصلي.",
        "specialloguserlabel": "المؤدي:",
-       "speciallogtitlelabel": "اÙ\84Ù\87دÙ\81 (عÙ\86Ù\88اÙ\86 Ø£Ù\88 مستخدم):",
+       "speciallogtitlelabel": "اÙ\84Ù\87دÙ\81 (عÙ\86Ù\88اÙ\86 Ø§Ù\88 {{ns:user}}:username Ù\84Ù\84مستخدم):",
        "log": "سجلات",
        "logeventslist-submit": "أظهر",
        "all-logs-page": "كل السجلات العامة",
        "listgrouprights-namespaceprotection-namespace": "النطاق",
        "listgrouprights-namespaceprotection-restrictedto": "الصلاحيات التي تسمح للمستخدم بالتعديل",
        "listgrants": "المنح",
+       "listgrants-summary": "التالي هو قائمة بالمنح بعمليات الوصول لصلاحيات المستخدم المصاحبة لها. المستخدمون يمكنهم إعطاء صلاحية للتطبيقات لاستخدام حساباتهم، ولكن بسماحات محدودة بناء على المنح التي أعطاها المستخدم للتطبيق. تطبيق يعمل بالنيابة عن مستخدم لا يمكنه استخدام الصلاحيات التي لا يمتلكها المستخدم بالفعل.\nربما تكون هناك [[{{MediaWiki:Listgrouprights-helppage}}|معلومات إضافية]] حول الصلاحيات الفردية.",
        "listgrants-grant": "المنحة",
        "listgrants-rights": "الصلاحيات",
        "trackingcategories": "تصانيف التتبع",
        "trackingcategories-msg": "تصانيف التتبع",
        "trackingcategories-name": "اسم الرسالة",
        "trackingcategories-desc": "معايير إدراج تصنيف",
+       "restricted-displaytitle-ignored": "الصفحات بعناوين عرض تم تجاهلها",
+       "restricted-displaytitle-ignored-desc": "هذه الصفحة تحتوي على <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> تم تجاهله لأنه لا يساوي عنوان الصفحة الفعلي.",
        "noindex-category-desc": "هذه الصفحة لا تفهرسها الروبوتات لأن فيها الكلمة السحرية <code><nowiki>__NOINDEX__</nowiki></code> ولأنها في نطاق يسمح بهذا العلم.",
        "index-category-desc": "الصفحة فيها <code><nowiki>__INDEX__</nowiki></code> (وهي في نطاق يسمح بهذا العلم) ولذا فالروبوتات تفهرسها بينما الأصل ألا تفعل.",
        "post-expand-template-inclusion-category-desc": "بعد توسيع جميع القوالب حجم الصفحة أكبر من <code><nowiki>__INDEX__</nowiki></code> ولذا فبعض القوالب لا تُوسّع.",
        "emailccsubject": "نسخة من رسالتك إلى $1: $2",
        "emailsent": "أُرسل البريد الإلكتروني",
        "emailsenttext": "أُرسلت رسالتك الإلكترونية.",
-       "emailuserfooter": "هذا البريد الإلكتروني تم إرساله بواسطة $1 إلى $2 بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}.",
+       "emailuserfooter": "هذا البريد الإلكتروني {{GENDER:$1|تم إرساله}} بواسطة $1 إلى {{GENDER:$2|$2}} بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}.",
        "usermessage-summary": "ترك رسالة نظام.",
        "usermessage-editor": "مراسل النظام",
        "watchlist": "قائمة مراقبتي",
        "watchnologin": "غير مسجل الدخول",
        "addwatch": "إضافة إلى قائمة المراقبة",
        "addedwatchtext": "\"[[:$1]]\" وصفحة نقاشها أضيفتا إلى [[Special:Watchlist|قائمة مراقبتك]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" وصفحتها المرافقة تمت إضافتها إلى [[Special:Watchlist|قائمة مراقبتك]].",
        "addedwatchtext-short": "أضيفت صفحة \"$1\" إلى قائمة مراقبتك.",
        "removewatch": "إزالة من قائمة المراقبة",
        "removedwatchtext": "\"[[:$1]]\" وصفحة نقاشها أزيلتا من [[Special:Watchlist|قائمة مراقبتك]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" وصفحتها المرافقة تمت إزالتها من [[Special:Watchlist|قائمة مراقبتك]].",
        "removedwatchtext-short": "أزيلت صفحة \"$1\" من قائمة مراقبتك.",
        "watch": "راقب",
        "watchthispage": "راقب هذه الصفحة",
        "deletepage": "حذف الصفحة",
        "confirm": "أكد",
        "excontent": "المحتوى كان: '$1'",
-       "excontentauthor": "المحتوى كان: '$1' (والمساهم الوحيد كان '[[Special:Contributions/$2|$2]]')",
+       "excontentauthor": "المحتوى كان: \"$1\" والمساهم الوحيد كان \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]])",
        "exbeforeblank": "المحتوى قبل الإفراغ كان: '$1'",
        "delete-confirm": "حذف \"$1\"",
        "delete-legend": "حذف",
        "delete-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقُيّد محذف مثل هذه الصفحات لمنع الاضطراب المفاجئة في {{SITENAME}}.",
        "delete-warning-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقد يؤدي حذفها إلى اضطراب عمليات قاعدة البيانات في {{SITENAME}}؛\nاستمر مع الحذر.",
        "deleteprotected": "لا يمكنك حذف هذه الصفحة لأنها محمية.",
-       "deleting-backlinks-warning": "[[Special:WhatLinksHere/{{FULLPAGENAME}}|تتصل صفحات أخرى]] بالصفحة التي تريد حذفها.",
+       "deleting-backlinks-warning": "<strong>تحذير:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|صفحات أخرى]] تصل إلى أو تضمن الصفحة التي أنت على وشك حذفها.",
        "rollback": "التراجع عن التعديلات",
        "rollbacklink": "استرجع",
        "rollbacklinkcount": "استرجع {{PLURAL:$1|لا تعديلات|تعديلا واحدا|تعديلين|$1 تعديلات|$1 تعديلاً|تعديل}}",
        "rollbacklinkcount-morethan": "استرجاع أكثر من {{PLURAL:$1|تعديل|تعديل|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}",
        "rollbackfailed": "لم ينجح الاسترجاع",
+       "rollback-missingparam": "محددات مطلوبة مفقودة عند الطلب.",
+       "rollback-missingrevision": "غير قادر على تحميل بيانات المراجعة.",
        "cantrollback": "لم يمكن استرجاع التعديل؛\nآخر مساهم هو المؤلف الوحيد لهذه الصفحة.",
        "alreadyrolled": "لم يمكن استرجاع آخر تعديل ل[[$1]] بواسطة [[User:$2|$2]] ([[User talk:$2|نقاش]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])؛\nشخص آخر عدل أو استرجع الصفحة بالفعل.\n\nآخر تعديل كان بواسطة [[User:$3|$3]] ([[User talk:$3|نقاش]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "ملخص التعديل كان:<em>$1</em>.",
        "revertpage": "استرجع تعديلات [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]]) حتى آخر مراجعة ل[[User:$1|$1]]",
        "revertpage-nouser": "استرجع تعديلات مستخدم مخفي حتى آخر مراجعة ل{{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "استرجع تعديلات $1؛\nاسترجع حتى آخر نسخة بواسطة $2.",
+       "rollback-success-notify": "تم استرجاع التعديلات بواسطة $1;\nتم التغيير إلى آخر مراجعة بواسطة $2. [$3 عرض التغييرات]",
        "sessionfailure-title": "فشل في الجلسة",
        "sessionfailure": "يبدو أنه هناك مشكلة في جلسة الدخول الخاصة بك؛\nلذلك فقد ألغيت هذه العملية كإجراء احترازي ضد الاختراق.\nمن فضلك اضغط على مفتاح \"رجوع\" لتحميل الصفحة التي جئت منها، ثم حاول مرة أخرى.",
        "changecontentmodel": "غير نموذج المحتوى لصفحة",
        "changecontentmodel-success-text": "نوع المحتوى ل[[:$1]] تم تغييره.",
        "changecontentmodel-cannot-convert": "المحتوى على [[:$1]] لا يمكن تحويله لنوع من $2.",
        "changecontentmodel-nodirectediting": "نموذج المحتوى $1 لا يدعم التعديل المباشر",
+       "changecontentmodel-emptymodels-title": "لا موديلات محتوى متوفرة",
+       "changecontentmodel-emptymodels-text": "المحتوى على[[:$1]] لا يمكن تغييره لأي نوع.",
        "log-name-contentmodel": "سجل تغيير نموذج المحتوى",
        "log-description-contentmodel": "الأحداث المرتبطة بنماذج المحتوى لصفحة",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|أنشأ|أنشأت}} الصفحة $3 باستخدام موديل محتوى غير قياسي \"$5\"",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|غير|غيرت}} موديل المحتوى للصفحة $3 من \"$4\" إلى \"$5\"",
        "logentry-contentmodel-change-revertlink": "استرجع",
        "logentry-contentmodel-change-revert": "استرجع",
        "protectlogpage": "سجل الحماية",
        "undeletehistorynoadmin": "هذه الصفحة تم حذفها.\nالسبب للحذف معروض في الملخص بالأسفل، إلى جانب تفاصيل المستخدمين الذين قاموا بالتعديل على هذه الصفحة قبل حذفها.\nنص المراجعات المحذوفة هذه متوفر فقط للإداريين.",
        "undelete-revision": "المراجعة المحذوفة ل$1 (بتاريخ $4، الساعة $5) بواسطة $3:",
        "undeleterevision-missing": "مراجعة غير صحيحة أو مفقودة.\nربما لديك وصلة سيئة، أو ربما المراجعة تم استرجاعها أو إزالتها من الأرشيف.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|مراجعة واحدة|$1 مراجعة}} لم يمكن استعادتها, لأن ال<code>rev_id</code> {{PLURAL:$1|الخاص بها}}  كان مستخدما بالفعل.",
        "undelete-nodiff": "لم يتم العثور على مراجعة سابقة.",
        "undeletebtn": "استرجاع",
        "undeletelink": "اعرض/استعد",
        "undeletedrevisions": "تم استرجاع {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلا|$1 تعديل}}",
        "undeletedrevisions-files": "أسترجعت {{PLURAL:$1||مراجعة واحدة|مراجعتان|$1 مراجعات|$1 مراجعة}}  و{{PLURAL:$2||ملف واحد|ملفان|$2 ملفات|$2 ملفًا|$2 ملف}}",
        "undeletedfiles": "أسترجع {{PLURAL:$1||ملف واحد|ملفان|$1 ملفات|$1 ملفًا|$1 ملف}}",
-       "cannotundelete": "فشل الاسترجاع؛\n$1",
+       "cannotundelete": "بعض أو كل عملية الاسترجاع فشلت:\n$1",
        "undeletedpage": "'''تم استرجاع $1'''\n\nراجع [[Special:Log/delete|سجل الحذف]] لمعاينة عمليات الحذف والاسترجاعات الحديثة.",
        "undelete-header": "انظر الصفحات المحذوفة حديثا في [[Special:Log/delete|سجل الحذف]].",
        "undelete-search-title": "البحث في الصفحات المحذوفة",
        "sp-contributions-newbies-sub": "للحسابات الجديدة",
        "sp-contributions-newbies-title": "مساهمات المستخدم للحسابات الجديدة",
        "sp-contributions-blocklog": "سجل المنع",
-       "sp-contributions-suppresslog": "مساهمات المستخدم المحذوفة",
-       "sp-contributions-deleted": "مساهمات المستخدم المحذوفة",
+       "sp-contributions-suppresslog": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}} المخفية",
+       "sp-contributions-deleted": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}} المحذوفة",
        "sp-contributions-uploads": "مرفوعات",
        "sp-contributions-logs": "سجلات",
        "sp-contributions-talk": "نقاش",
        "unblock": "إلغاء منع مستخدم",
        "blockip": "منع {{GENDER:$1|المستخدم|المستخدمة}}",
        "blockip-legend": "منع المستخدم",
-       "blockiptext": "استخدم النموذج التالي لمنع مستخدم، أو عنوان آيبي، معين من التعديل أو إنشاء حسابات جديدة. تُستخدم هذه العملية لمنع التخريب فقط، ويجب أن تتماشى مع [[{{MediaWiki:Policy-url}}|سياسة المنع]]. أدخل تعليلاً واضحًا لسبب المنع في الخانة المخصصة لذلك (مثلاً: ذكر صفحات محددة تمّ تخريبها من قبل المستخدم).",
+       "blockiptext": "استخدم النموذج التالي لمنع مستخدم، أو عنوان آيبي، معين من التعديل أو إنشاء حسابات جديدة. تُستخدم هذه العملية لمنع التخريب فقط، ويجب أن تتماشى مع [[{{MediaWiki:Policy-url}}|سياسة المنع]]. أدخل تعليلاً واضحًا لسبب المنع في الخانة المخصصة لذلك (مثلاً: ذكر صفحات محددة تمّ تخريبها من قبل المستخدم).\nيمكنك منع نطاقات عناوين IP باستخدام [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] قواعد; أكبر نطاق مسموح به هو /$1 إلى IPv4 و /$2 إلى IPv6.",
        "ipaddressorusername": "عنوان الأيبي أو اسم المستخدم:",
        "ipbexpiry": "مدة المنع:",
        "ipbreason": "السبب:",
        "ipbreason-dropdown": "*أسباب المنع الشائعة\n** كتابة معلومات زائفة\n** إزالة المحتوى من الصفحات\n** سبام وصلات لمواقع خارجية\n** كتابة كلام لا معنى له في الصفحات\n** سلوك عدواني\n** إساءة استخدام حسابات متعددة\n** اسم مستخدم غير مقبول",
-       "ipb-hardblock": "اÙ\85Ù\86ع Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\88اÙ\84جÙ\8aÙ\86 Ù\85Ù\86 Ø§Ù\84تعدÙ\8aÙ\84 Ø¨Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84Ø¢يبي هذا",
+       "ipb-hardblock": "اÙ\85Ù\86ع Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\88اÙ\84جÙ\8aÙ\86 Ù\85Ù\86 Ø§Ù\84تعدÙ\8aÙ\84 Ø¨Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84Ø£يبي هذا",
        "ipbcreateaccount": "امنع إنشاء الحسابات",
        "ipbemailban": "امنع المستخدم من إرسال بريد إلكتروني",
        "ipbenableautoblock": "تلقائيا امنع آخر عنوان أيبي تم استعماله بواسطة هذا المستخدم، وأي عناوين أيبي أخرى يحاول التحرير من خلالها",
        "lockedbyandtime": "(من $1 على $2 في $3 )",
        "move-page": "نقل $1",
        "move-page-legend": "نقل صفحة",
-       "movepagetext": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.\nإذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه '''لن يتم''' نقل الصفحة إذا وجدت صفحة في العنوان الجديد، إلا إذا كانت صفحة تحويل، ولا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، وأنك لا يمكنك نسخ هذه الصفحة فوق صفحة موجودة.\n\n'''تحذير!'''\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
-       "movepagetext-noredirectfixer": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك تحديث التحويلات التي تشير إلى العنوان الأصلي تلقائياً.\nلو اخترت ألا تفعل، تأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]].\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه '''لن يتم''' نقل الصفحة إذا كان هناك صفحة بنفس العنوان الجديد، إلا إذا كانت فارغة، أو تحويلة لا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، وأنك لا يمكنك الكتابة على صفحة موجودة.\n\n'''تحذير!'''\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
-       "movepagetalktext": "صفحة النقاش المرفقة سيتم نقلها كذلك، '''إلا في حالة''':\n* توجد صفحة نقاش غير فارغة تحت العنوان الجديد، أو\n* قمت بإزالة اختيار الصندوق بالأسفل.\n\nوفي هذه الحالات، يجب عليك نقل أو دمج محتويات الصفحة يدويا، إذا رغب في ذلك.",
+       "movepagetext": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.\nإذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong> نقل الصفحة إذا وجدت صفحة في العنوان الجديد، إلا إذا كانت صفحة تحويل، ولا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، ولا يمكنك نسخ هذه الصفحة فوق صفحة موجودة.\n\n<strong>ملاحظة:</strong>\n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
+       "movepagetext-noredirectfixer": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك تحديث التحويلات التي تشير إلى العنوان الأصلي تلقائياً.\nلو اخترت ألا تفعل، تأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]].\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong>  نقل الصفحة إذا كان هناك صفحة بنفس العنوان الجديد، إلا إذا كانت فارغة، أو تحويلة لا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، وأنك لا يمكنك الكتابة على صفحة موجودة.\n\n<strong>ملاحظة</strong> \n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
+       "movepagetalktext": "لو علمت على هذا الصندوق، فصفحة النقاش المرفقة يتم نقلها أوتوماتيكيا للعنوان الجديد، إلا لو كانت صفحة نقاش غير فارغة هناك بالفعل.\n\nفي هذه الحالة، فسيتعين عليك نقل أو دمج الصفحة يدويا لو رغبت في ذلك.",
        "moveuserpage-warning": "'''تحذير: أنت على وشك نقل صفحة مستخدم. من فضلك لاحظ أن الصفحة وحدها سوف تنقل وأن المستخدم لن يعاد تسميته.'''",
        "movecategorypage-warning": "<strong>تحذير:</strong> أنت على وشك نقل صفحة التصنيف إلى عنوان جديد؛ <em>لن</em> تنقل الصفحات المندرجة تحت التصنيف إلى العنوان الجديد.",
        "movenologintext": "يجب أن تكون مستخدماً مسجلاً وأن  [[Special:UserLogin|تسجل دخولك]] لكي تنقل صفحة.",
        "movenosubpage": "ليس لهذه الصفحة صفحات فرعية.",
        "movereason": "السبب:",
        "revertmove": "استرجع",
-       "delete_and_move_text": "==الحذف مطلوب==\nالصفحة الهدف \"[[:$1]]\" موجودة بالفعل.\nهل تريد حذفها لإفساح المجال للنقل؟",
+       "delete_and_move_text": "الصفحة الهدف \"[[:$1]]\" موجودة بالفعل.\nهل تريد حذفها لإفساح المجال للنقل؟",
        "delete_and_move_confirm": "نعم، احذف الصفحة",
        "delete_and_move_reason": "حُذِفت لإفساح مجال لنقل \"[[$1]]\"",
        "selfmove": "لا يوجد اختلاف في عنوان المصدر والهدف؛\nلا يمكن نقل الصفحة على نفسها.",
        "move-leave-redirect": "اترك تحويلة خلفك",
        "protectedpagemovewarning": "'''تحذير:''' هذه الصفحة قد تم حمايتها، فقط المستخدمون الذين يمتلكون امتيازات الإدارة يمكنهم نقلها.\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
        "semiprotectedpagemovewarning": "'''ملاحظة:''' هذه الصفحة تمت حمايتها ليتمكن المستخدمون المسجلون وحدهم من نقلها.\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
-       "move-over-sharedrepo": "== الملف موجود ==\n[[:$1]] موجود في مستودع مشترك. نقل الملف إلى هذا العنوان سوف يلغي الملف المشترك.",
+       "move-over-sharedrepo": "[[:$1]] موجود في مستودع مشترك. نقل الملف إلى هذا العنوان سوف يلغي الملف المشترك.",
        "file-exists-sharedrepo": "اسم الملف الذي اخترته مستخدم من قبل في مستودع مشترك.\nمن فضلك اختر اسماً آخر.",
        "export": "تصدير صفحات",
        "exporttext": "يمكنك تصدير النص وتاريخ تعديلات صفحة أو مجموعة صفحات في صيغة XML.\nهذا يمكن استيراده إلى ويكي آخر يستعمل ميدياويكي بواسطة [[Special:Import|صفحة الاستيراد]].\n\nلتصدير الصفحات، أدخل عناوينها في الصندوق أسفله، عنواناً واحداً في كل سطر، مع اختيار ما إذا كنت ترغب بتصدير النسخة الحالية مع جميع النسخ القديمة، أي مع كامل معلومات تاريخ الصفحة، أو فقط النسخة الحالية مع معلومات عن التعديل الأخير.\n\nفي الحالة الأخيرة يمكنك أيضاً استخدام وصلة، على سبيل المثال [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] للصفحة «[[{{MediaWiki:Mainpage}}]]».",
        "import-nonewrevisions": "لا مراجعات تم استيرادها (كل المراجعات إما أنها كانت موجودة بالفعل، وأو تم تجاوزها نتيجة أخطاء).",
        "xml-error-string": "$1 عند السطر $2، العمود $3 (بايت $4): $5",
        "import-upload": "رفع بيانات XML",
-       "import-token-mismatch": "فقد لبيانات الجلسة. من فضلك حاول مرة أخرى.",
+       "import-token-mismatch": "فقد لبيانات الجلسة.\n\nأنت لابد من أنه قد تم تسجيل خروجك. <strong>من فضلك تأكد من أنك مازلت مسجل الدخول وحاول مرة أخرى</strong>.\nلو كان مازال لا يعمل، فحاول [[Special:UserLogout|تسجيل الخروج]] وتسجيل الدخول مرة أخرى، وتحقق من أن متصفحك يسمح بالكوكيز من هذا الموقع.",
        "import-invalid-interwiki": "لم يمكن الاستيراد من الويكي المحدد.",
        "import-error-edit": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك تحريرها.",
        "import-error-create": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك استحداثها أصلا.",
        "tooltip-ca-nstab-category": "رؤية صفحة التصنيف",
        "tooltip-minoredit": "علم على هذا كتعديل طفيف",
        "tooltip-save": "احفظ تغييراتك",
+       "tooltip-publish": "انشر تغييراتك",
        "tooltip-preview": "اعرض تغييراتك، من فضلك استخدم هذا قبل الحفظ!",
        "tooltip-diff": "اعرض التغييرات التي قمت بها للنص.",
        "tooltip-compareselectedversions": "شاهد الفروق بين النسختين المختارتين من هذه الصفحة.",
        "hours-ago": "منذ {{PLURAL:$1|ساعة|$1 ساعات}}",
        "minutes-ago": "منذ {{PLURAL:$1|دقيقة|$1 دقائق}}",
        "seconds-ago": "منذ {{PLURAL:$1|ثانية|$1 ثوان}}",
-       "monday-at": "Ù\8aÙ\88Ù\85 Ø§Ù\84اثنين الساعة $1",
+       "monday-at": "Ù\8aÙ\88Ù\85 Ø§Ù\84Ø¥ثنين الساعة $1",
        "tuesday-at": "يوم الثلاثاء الساعة $1",
        "wednesday-at": "يوم الأربعاء الساعة $1",
        "thursday-at": "يوم الخميس الساعة $1",
        "exif-artist": "المؤلف",
        "exif-copyright": "مالك الحقوق",
        "exif-exifversion": "نسخة Exif",
-       "exif-flashpixversion": "نسخة فلاش بكس المدعومة",
+       "exif-flashpixversion": "نسخة Flashpix المدعومة",
        "exif-colorspace": "فضاء الألوان",
        "exif-componentsconfiguration": "معنى كل مكونة",
        "exif-compressedbitsperpixel": "طور ضغط الصورة",
        "exif-iimcategory-edu": "تعليم",
        "exif-iimcategory-evn": "بيئة",
        "exif-iimcategory-hth": "صحة",
-       "exif-iimcategory-hum": "اهتمام البشرية",
+       "exif-iimcategory-hum": "اهتمام البشرية",
        "exif-iimcategory-lab": "عمل",
        "exif-iimcategory-lif": "أسلوب الحياة وأوقات الفراغ",
        "exif-iimcategory-pol": "سياسة",
        "confirmemail_body_set": "شخص ما -من المحتمل أن يكون أنت- من عنوان الأيبي $1 غيّر عنوان البريد\nالإلكتروني للحساب \"$2\" إلى عنوان البريد الإلكتروني هذا في\n{{SITENAME}}.\n\nلتأكيد أن هذا الحساب لك فعلا ولتنشيط خواص البريد الإلكتروني في\n{{SITENAME}}، افتح هذه الوصلة في متصفحك:\n\n$3\n\nإذا كان هذا الحساب *ليس* لك، اتبع هذه الوصلة لإلغاء تأكيد عنوان البريد\nالإلكتروني:\n\n$5\n\nسينتهي رمز التفعيل هذا في $4.",
        "confirmemail_invalidated": "تأكيد عنوان البريد الإلكتروني تم إلغاؤه",
        "invalidateemail": "إلغاء تأكيد البريد الإلكتروني",
+       "notificationemail_subject_changed": "عنوان البريد الإلكتروني المسجل ل{{SITENAME}} تم تغييره",
+       "notificationemail_subject_removed": "عنوان البريد الإلكتروني المسجل ل{{SITENAME}} تمت إزالته",
+       "notificationemail_body_changed": "شخص ما، غالبا أنت،  من عنوان الأيبي $1،\nقام بتغيير عنوان البريد الإلكتروني للحساب \"$2\" إلى \"$3\" في {{SITENAME}}.\n\nلو أن هذا لم يكن أنت، فاتصل بإداري للموقع حالا.",
+       "notificationemail_body_removed": "شخص ما، غالبا أنت،  من عنوان الأيبي $1،\nقام بإزالة عنوان البريد الإلكتروني للحساب \"$2\" في {{SITENAME}}.\n\nلو أن هذا لم يكن أنت، فاتصل بإداري للموقع حالا.",
        "scarytranscludedisabled": "[التضمين بالإنترويكي معطل]",
        "scarytranscludefailed": "[البحث عن القالب فشل ل$1]",
        "scarytranscludefailed-httpstatus": "[فشل جلب القالب لـ $1: HTTP $2]",
        "scarytranscludetoolong": "[المسار طويل للغاية]",
        "deletedwhileediting": "'''تحذير''': هذه الصفحة تم حذفها بعد أن بدأت أنت بتعديلها!",
-       "confirmrecreate": "حذف المستخدم [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها للسبب التالي:\n:''$2''\nالرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
-       "confirmrecreate-noreason": "حذف المستخدم [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها. الرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
+       "confirmrecreate": "{{GENDER:$1|حذف المستخدم|حذفت المستخدمة}} [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها للسبب التالي:\n: <em>$2</em>\nالرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
+       "confirmrecreate-noreason": "{{GENDER:$1|حذف المستخدم|حذفت المستخدمة}} [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها. الرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
        "recreate": "إعادة إنشاء",
        "unit-pixel": "بك",
        "confirm_purge_button": "موافق",
        "confirm-unwatch-button": "موافق",
        "confirm-unwatch-top": "إزالة هذه الصفحة من قائمة مراقبتك؟",
        "confirm-rollback-button": "موافق",
+       "confirm-rollback-top": "استرجاع التعديلات لهذه الصفحة؟",
        "semicolon-separator": "؛&#32;",
        "comma-separator": "،&#32;",
        "quotation-marks": "«$1»",
        "timezone-local": "محلي",
        "duplicate-defaultsort": "'''تحذير:''' مفتاح الترتيب الافتراضي \"$2\" يتجاوز مفتاح الترتيب الافتراضي السابق \"$1\".",
        "duplicate-displaytitle": "<strong>تحذير:</strong> أعرض عنوان \"$2\" تجاهل العنوان المعروض سابقا \"$1\".",
+       "restricted-displaytitle": "<strong>تحذير:</strong> عنوان العرض \"$1\" تم تجاهله بما أنه لا يساوي عنوان الصفحة الفعلي.",
        "invalid-indicator-name": "<strong>خطأ:</strong> لا يجوز أن تبقى خاصية <code>name</code> لمؤشرات وضع الصفحة فارغةً.",
        "version": "نسخة",
        "version-extensions": "الامتدادات المثبتة",
        "version-libraries-description": "الوصف",
        "version-libraries-authors": "المؤلفون",
        "redirect": "تحويل حسب الملف أو المستخدم أو الصفحة أو معرف الدخول",
-       "redirect-summary": "هذه الصفحة الخاصة تحوّل إلى ملف (باسمه) أو صفحة (برقم إحدى مراجعاتها) أو إلى صفحة مستخدم (برقمه التعريفي). الاستخدام [[{{#Special:Redirect}}/file/Example.jpg]] أو [[{{#Special:Redirect}}/revision/328429]] أو [[{{#Special:Redirect}}/user/101]].",
-       "redirect-submit": "Ø­Ù\88Ù\91Ù\84",
+       "redirect-summary": "هذه الصفحة الخاصة تحوّل إلى ملف (باسمه) أو صفحة (برقم إحدى مراجعاتها) أو إلى صفحة مستخدم (برقمه التعريفي) أو إلى مدخلة سجل (برقم السجل). الاستخدام [[{{#Special:Redirect}}/file/Example.jpg]] أو [[{{#Special:Redirect}}/revision/328429]] أو [[{{#Special:Redirect}}/user/101]] أو [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "اذÙ\87ب",
        "redirect-lookup": "ابحث في:",
        "redirect-value": "الوجهة",
        "redirect-user": "رقم مستخدم",
        "tags-create-reason": "السبب:",
        "tags-create-submit": "أنشئ",
        "tags-create-no-name": "عليك أن تحدد اسم الوسم.",
+       "tags-create-invalid-chars": "أسماء الوسوم ينبغي ألا تحتوي على فواصل (<code>,</code>) أو forward slashes (<code>/</code>).",
        "tags-create-invalid-title-chars": "يجب أن لا تحتوي أسماء العلامات الأحرف التي لا يمكن استخدامها في عناوين الصفحات.",
        "tags-create-already-exists": "الوسم \"$1\" موجود بالفعل.",
+       "tags-create-warnings-above": "{{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}} عند محاولة إنشاء الوسم \"$1\":",
        "tags-create-warnings-below": "هل تود متابعة إنشاء الوسم؟",
        "tags-delete-title": "احذف الوسم",
        "tags-delete-explanation-initial": "أنت على وشك حذف الوسم \"$1\" من قاعدة البيانات.",
+       "tags-delete-explanation-in-use": "ستتم إزالته من {{PLURAL:$2|$2 مراجعة او مدخلة سجل|كل $2 مراجعات و/أو مدخلات سجل}} الذي هو مطبق عليهم حاليا.",
+       "tags-delete-explanation-warning": "هذا الفعل <strong>غير رجعي</strong> و <strong>لا يمكن التراجع عنه</strong>، ولا حتى بواسطة إداريي قاعدة البيانات. كن متاكدا من أن هذا هو الوسم الذي تريد حذفه.",
+       "tags-delete-explanation-active": "<strong>الوسم \"$1\" مازال نشطا، وسيتم الاستمرار في تطبيقه في المستقبل.</strong> لمنع هذا من الحدوث، اذهب إلى المكان(الأمكنة) حيث الوسم مضبوط ليتم تطبيقه، وعطله هناك.",
        "tags-delete-reason": "سبب:",
-       "tags-delete-submit": "إزاÙ\84Ø© هذا الوسم دون رجعة (ستدمر بعض البيانات)",
+       "tags-delete-submit": "حذÙ\81 هذا الوسم دون رجعة (ستدمر بعض البيانات)",
        "tags-delete-not-allowed": "الوسوم التي يعرفها امتداد لا يمكن حذفها إلا إذا أتاح الامتداد ذلك.",
        "tags-delete-not-found": "الوسم \"$1\" غير موجود.",
+       "tags-delete-too-many-uses": "الوسم \"$1\" مطبق في أكثر من $2 {{PLURAL:$2|مراجعة|مراجعات}}، مما يعني أنه لا يمكن حذفه.",
+       "tags-delete-warnings-after-delete": "الوسم \"$1\" تم حذفه، لكن {{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}}:",
+       "tags-delete-no-permission": "أنت لا تمتلك الصلاحية لحذف وسوم التغيير.",
        "tags-activate-title": "نشط الوسم",
        "tags-activate-question": "أنت على وشك تنشيط الوسم \"$1\".",
        "tags-activate-reason": "السبب:",
        "tags-deactivate-submit": "عطل",
        "tags-apply-no-permission": "ليس لديك إذن لتطبيق علامات التغيير جنبا إلى جنب مع التغييرات.",
        "tags-apply-blocked": "لا يمكنك تطبيق علامات التغيير جنبا إلى جنب مع التغييرات في حين منعت.",
-       "tags-apply-not-allowed-one": "السوم \"$1\" غير مسموح أن يتم تطبيقه يدويا.",
+       "tags-apply-not-allowed-one": "الوسم \"$1\" غير مسموح أن يتم تطبيقه يدويا.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|الوسم|الوسوم}} التالية غير مسموح أن يتم تطبيقها يدويا: $1",
        "tags-update-no-permission": "أنت لا تمتلك السماح لإضافة أو إزالة وسوم التغيير من المراجعات أو مدخلات السجل الفردية.",
        "tags-update-blocked": "لا يمكنك إضافة أو إزالة العلامات التغيير بينماهي محظورة.",
        "tags-edit-revision-selected": "{{PLURAL:$1|مراجعة مختارة|مراجعات مختارة}} من [[:$2]]:",
        "tags-edit-logentry-selected": "{{PLURAL:$1|حدث سجل مختار|أحداث سجل مختارة}}:",
        "tags-edit-revision-legend": "أضف أو أزل الوسوم من {{PLURAL:$1|هذه المراجعة|كل $1 المراجعات}}",
+       "tags-edit-logentry-legend": "أضف أو أزل الوسوم من {{PLURAL:$1|مدخلة السجل هذه|كل مدخلات السجل ال$1}}",
        "tags-edit-existing-tags": "الوسوم الموجودة:",
        "tags-edit-existing-tags-none": "</em>لا وسوم</em>",
        "tags-edit-new-tags": "وسوم جديدة:",
        "logentry-block-unblock": "$1 {{GENDER:$2|رفع منع}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": " {{GENDER:$2|غير|غيرت}} $1 إعدادات المنع ل{{GENDER:$4|$3}} بتاريخ انتهاء $5 $6",
        "logentry-suppress-block": "{{GENDER:$2|منع|منعت}} $1 {{GENDER:$4|$3}} لفترة زمنية مدتها $5 $6",
+       "logentry-suppress-reblock": "$1 {{GENDER:$2|غير|غيرت}} إعدادات المنع ل{{GENDER:$4|$3}} بتاريخ انتهاء $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|استورد}} $3 بواسطة رفع ملف",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|استورد|استوردت}} $3 بواسطة رفع الملف ($4 {{PLURAL:$4|مراجعة|مراجعات}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|استورد|استوردت}} $3 من ويكي أخرى",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|استورد|استوردت}} $3 من $5 ($4 {{PLURAL:$4|مراجعة|مراجعات}})",
        "logentry-merge-merge": "{{GENDER:$2|دمج|دمجت}} $1 $3 إلى $4 (المراجعات حتى $5).",
        "logentry-move-move": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4",
        "logentry-move-move-noredirect": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4 دون ترك تحويلة",
        "logentry-protect-protect": "$1 {{GENDER:$2|حمى|حمت}} $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|حمى|حمت}} $3 $4 [مضمنة]",
        "logentry-protect-modify": "{{GENDER:$2|غير|غيرت}} $1 مستوى حماية $3 $4",
-       "logentry-rights-rights": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3 من $4 إلى $5",
+       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|غير|غيرت}} مستوى الحماية ل$3 $4 [مضمن]",
+       "logentry-rights-rights": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية {{GENDER:$6|$3}} من $4 إلى $5",
        "logentry-rights-rights-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3",
        "logentry-rights-autopromote": "تمت تلقائيا ترقية {{GENDER:$2|المستخدم|المستخدمة}} $1 من  $4 إلى $5",
        "logentry-upload-upload": " {{GENDER:$2|رفع|رفعت}} $1 $3",
        "logentry-upload-overwrite": "{{GENDER:$2|رفع|رفعت}} $1 نسخة جديدة من  $3",
        "logentry-upload-revert": "{{GENDER:$2|رفع|رفعت}} $1 $3",
        "log-name-managetags": "سجل إدارة الوسوم",
+       "log-description-managetags": "هذه الصفحة تعرض مهام الإدارة المرتعلقة ب[[Special:Tags|الوسوم]]. السجل يحتوي فقط على الافعال التي تم عملها يدويا بواسطة إداري؛ الوسوم ربما يتم إنشاؤها او حذفها بواسطة برنامج الويكي بدون تسجيل مدخلة في هذا السجل.",
        "logentry-managetags-create": "$1 {{GENDER:$2|أنشأ|أنشأت}} الوسم \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|حذف|حذفت}} الوسم \"$4\" (أزيل من $5 {{PLURAL:$5|مراجعة أو مدخلة سجل|مراجعات و/أو مدخلات سجل}})",
        "logentry-managetags-activate": "$1 {{GENDER:$2|فعل|فعلت}} الوسم \"$4\" للاستخدام بواسطة البوتات والمستخدمين",
        "logentry-managetags-deactivate": "$1 {{GENDER:$2|ألغى تفعيل|ألغت تفعيل}} الوسم \"$4\" للاستخدام بواسطة البوتات والمستخدمين",
        "log-name-tag": "سجل الوسوم",
+       "log-description-tag": "هذه الصفحة تعرض متى قام المستخدمون بإضافة أو إزالة [[Special:Tags|الوسوم]] من المراجعات أو مدخلات السجل الفردية. السجل لا يعرض أفعال الوسم عندما يحدثوا كجزء من تعديل، حذف، أو فعل مماثل.",
+       "logentry-tag-update-add-revision": "$1 {{GENDER:$2|أضاف|أضافت}} {{PLURAL:$7|الوسم|الوسوم}} $6 للمراجعة $4 للصفحة $3",
+       "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|أضاف|أضافت}} {{PLURAL:$7|الوسم|الوسوم}} $6 لمدخلة السجل $5 للصفحة $3",
+       "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|أزال|أزالت}} {{PLURAL:$9|الوسم|الوسوم}} $8 من المراجعة $4 للصفحة $3",
+       "logentry-tag-update-remove-logentry": "$1 {{GENDER:$2|أزال|أزالت}} {{PLURAL:$9|الوسم|الوسوم}} $8 من مدخلة السجل $5 للصفحة $3",
+       "logentry-tag-update-revision": "$1 {{GENDER:$2|حدث|حدثت}} الوسوم للمراجعة $4 للصفحة $3 ({{PLURAL:$7|أضاف}} $6; {{PLURAL:$9|أزال}} $8)",
+       "logentry-tag-update-logentry": "$1 {{GENDER:$2|حدث|حدثت}} الوسوم على مدخلة السجل $5 للصفحة $3 ({{PLURAL:$7|أضاف}} $6; {{PLURAL:$9|أزال}} $8)",
        "rightsnone": "(لا شيء)",
        "revdelete-summary": "ملخص التعديل",
        "feedback-adding": "إضافة تعليقات إلى الصفحة...",
        "feedback-close": "تم",
        "feedback-external-bug-report-button": "أرسل تقرير علة تقنية",
        "feedback-dialog-title": "أرسل تغذية راجعة",
+       "feedback-dialog-intro": "أنت يمكنك استخدام الاستمارة السهلة بالأسفل لإرسال تعليقك. تعليقك ستتم إضافته للصفحة \"$1\"، مع اسم المستخدم الخاص بك.",
        "feedback-error-title": "خطأ",
        "feedback-error1": "خطأ: لا يمكن التعرف عليها من API",
        "feedback-error2": "خطأ: فشل في تحرير",
        "feedback-message": "الرسالة:",
        "feedback-subject": "الموضوع:",
        "feedback-submit": "إرسال",
+       "feedback-terms": "أنا أفهم أن معلومات وكيل المستخدم الخاص بي تشمل معلومات حول نسخة متصفحي ونظام التشغيل الخاص بي بالضبط وستتم مشاركتها علنيا بجانب تعليقي.",
+       "feedback-termsofuse": "أنا أوافق على توفير تعليقات بالتوافق مع شروط الاستخدام.",
        "feedback-thanks": "شكرا! أُرسلت ملاحظاتك لصفحة \"[$2 $1]\".",
        "feedback-thanks-title": "شكرا لك!",
        "feedback-useragent": "وكيل المستخدم:",
        "searchsuggest-search": "بحث",
        "searchsuggest-containing": "يحتوي...",
+       "api-error-autoblocked": "عنوان الأيبي الخاص بك تم منعه تلقائيا، لأنه تم استخدامه بواسطة مستخدم ممنوع",
        "api-error-badaccess-groups": "لا يسمح لك بتحميل الملفات إلى هذه الويكي.",
        "api-error-badtoken": "خطأ داخلي: رمز مميز غير صحيح.",
        "api-error-blocked": "لقد منعت من التحرير.",
        "api-error-copyuploaddisabled": "تم تعطيل تحميل من رابط على هذا الخادم.",
-       "api-error-duplicate": "Ù\87Ù\86اÙ\83 {{PLURAL:$1|Ù\87Ù\88 Ù\85Ù\84Ù\81 Ø¢Ø®Ø±|Ù\83Ø°Ù\84Ù\83$2 Ø¨Ø¹Ø¶ Ø§Ù\84Ù\85Ù\84Ù\81ات Ø§Ù\84أخرÙ\89}} Ù\85سبÙ\82اÙ\8b Ø¹Ù\84Ù\89 Ø§Ù\84Ù\85Ù\88Ù\82ع Ø¨Ù\86Ù\81س Ø§Ù\84Ù\85ضÙ\85Ù\88Ù\86.",
+       "api-error-duplicate": "Ù\87Ù\86اÙ\83 {{PLURAL:$1|Ù\85Ù\84Ù\81 Ø¢Ø®Ø±|بعض Ø§Ù\84Ù\85Ù\84Ù\81ات Ø§Ù\84أخرÙ\89}} Ù\85سبÙ\82ا Ø¹Ù\84Ù\89 Ø§Ù\84Ù\85Ù\88Ù\82ع Ø¨Ù\86Ù\81س Ø§Ù\84Ù\85حتÙ\88Ù\89.",
        "api-error-duplicate-archive": "هناك {{PLURAL:$1|كان ملف آخر |كذلك بعض الملفات الأخرى}} مسبقاً على الموقع بنفس المضمون، ولكن {{PLURAL:$1|أنه تم | إجراء}} الحذف لها.",
        "api-error-empty-file": "كان ملف الذي قمت بإرسال فارغة.",
        "api-error-emptypage": "إنشاء صفحات فارغة جديدة، غير مسموح به.",
        "api-error-filetype-banned-type": "$1 {{PLURAL:$4|ليس نوع ملف مسموح به|ليست أنواع ملفات مسموح بها}}. {{PLURAL:$3|نوع الملف المسموح به هو|أنواع الملفات المسموح بها هي}} $2.",
        "api-error-filetype-missing": "يفتقد الملفّ ملحق نوعيّته.",
        "api-error-hookaborted": "التعديل الذي تحاول أن تقوم به تم إحباطه",
-       "api-error-http": "خطأ Ø¯Ø§Ø®Ù\84Ù\8a: ØªØ¹Ø°Ø± Ø§Ù\84اتصاÙ\84 Ø¨Ø§Ù\84خادÙ\88Ù\85.",
+       "api-error-http": "خطأ داخلي: تعذر الاتصال بالخادم.",
        "api-error-illegal-filename": "اسم الملف غير مسموح به.",
        "api-error-internal-error": "خطأ داخلي: حدث خطأ عند معالجة التحميل الخاص بك على الويكي.",
        "api-error-invalid-file-key": "خطأ داخلي: لم يتم العثور على الملف في التخزين المؤقت.",
        "api-error-nomodule": "خطأ داخلي: لم يتم تعيين تحميل الوحدة النمطية.",
        "api-error-ok-but-empty": "خطأ داخلي : لم يكن هناك استجابة من الملقم.",
        "api-error-overwrite": "لا يسمح بالكتابة فوق ملف موجود.",
+       "api-error-ratelimited": "أنت تحاول رفع الكثير من الملفات في فترة زمنية قصيرة أقصر مما تسمح به هذه الويكي.\nمن فضلك حاول مرة ثانية خلال عدة دقائق.",
        "api-error-stashfailed": "خطأ داخلي: فشل الملقم في تخزين الملفات المؤقتة.",
        "api-error-publishfailed": "خطأ داخلي: لم ينجح الخادوم في نشر ملف مؤقت",
        "api-error-stasherror": "حدث خطأ أثناء رفع الملف لتخزينه.",
        "api-error-stashnosuchfilekey": "الملف الذي كنت تحاول الوصول اليه في مخبوائتك غير موجود.",
        "api-error-timeout": "لم يستجب الملقم في الوقت المتوقع.",
        "api-error-unclassified": "حدث خطأ غير معروف",
-       "api-error-unknown-code": "خطأ غير معروف : \" $1 \"",
+       "api-error-unknown-code": "خطأ غير معروف: \"$1\"",
        "api-error-unknown-error": "خطأ داخلي: قد حدث خطأ عند محاولة تحميل الملف الخاص بك.",
-       "api-error-unknown-warning": "تحذير غير معروف:$1",
-       "api-error-unknownerror": "خطأ غير معروف : \" $1 \"",
-       "api-error-uploaddisabled": "تم تعطيل تحميل على هذا الويكي.",
-       "api-error-verification-error": "هذا الملف قد يكون معطوباً أو يحتوي على ملحق غير صحيح.",
+       "api-error-unknown-warning": "تحذير غير معروف: \"$1\"",
+       "api-error-unknownerror": "خطأ غير معروف: \"$1\"",
+       "api-error-uploaddisabled": "تم تعطيل الرفع على هذه الويكي.",
+       "api-error-verification-error": "هذا الملف قد يكون معطوباً أو يحتوي على امتداد غير صحيح.",
+       "api-error-was-deleted": "تم رفع ملف بهذا الاسم سابقا ثم تم حذفه بعد هذا.",
        "duration-seconds": "{{PLURAL:$1|أقل من ثانية|ثانية واحدة|ثانيتان|$1 ثوانٍ|$1 ثانية}}",
        "duration-minutes": "{{PLURAL:$1|أقل من دقيقة|دقيقة واحدة|دقيقتان|$1 دقائق|$1 دقيقة}}",
        "duration-hours": "({{PLURAL:$1||ساعة واحدة|ساعتان|$1 ساعات|$1 ساعة}})",
        "expand_templates_generate_rawhtml": "أظهر خام HTML",
        "expand_templates_preview": "عرض مسبق",
        "expand_templates_preview_fail_html": "<em>عذرا! لم نستطع معالجة تعديلك بسبب فقدان بيانات الجلسة.\n\nلأن {{SITENAME}} بها HTML الخام مفعلة، العرض المسبق مخفي كاحتياط ضد هجمات الجافا سكريبت.</em>\n\n<strong>إذا كانت هذه محاولة تعديل صادقة، من فضلك حاول مرة أخرى.</strong>\nإذا كانت مازالت لا تعمل، حاول [[Special:UserLogout|تسجيل الخروج]] ثم تسجيل الدخول مجددا.و تاكد في  متصفحك من الكوكيز  الخاصة  بهذا الموقع.",
+       "expand_templates_preview_fail_html_anon": "<em>لأن {{SITENAME}} لديه الHTML الخام مفعل وأنت غير مسجل الدخول، فعملية المعاينة مخفية كاحتياط ضد عمليات هجوم الجافاسكريبت.</em>\n\n<strong>لو أن هذه عملية معاينة صحيحة، فمن فضلك  [[Special:UserLogin|سجل الدخول]] وحاول مرة أخرى.</strong>",
        "expand_templates_input_missing": "يجب تقديم بعض المدخلات النصية على الأقل.",
        "pagelanguage": "تغيير لغة الصفحة",
        "pagelang-name": "صفحة",
        "log-name-pagelang": "سجل تغيير اللغة",
        "log-description-pagelang": "هذا سجل تغيرات في صفحة اللغات.",
        "logentry-pagelang-pagelang": " {{GENDER:$2|غيَّر|غيَّرت}} $1 لغة الصفحة «$3» من $4 إلى $5.",
+       "default-skin-not-found": "أخ! الواجهة الافتراضية للويكي الخاصة بك، والمعرفة في <code dir=\"ltr\">$wgDefaultSkin</code> ك<code>$1</code>، غير متوفرة.\n\nعملية تنصيبك يبدو أنها تحتوي على {{PLURAL:$4|الواجهة|الواجهات}} التالية. انظر [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] للمعلومات حول كيف تفعل  {{PLURAL:$4|ها|هم وتختار الافتراضي}}.\n\n$2\n\n; لو أنك قمت بتنصيب ميدياويكي حالا:\n: أنت ربما قمت بالتنصيب من git, أو مباشرة من الكود المصدري باستخدام طريقة أخرى. هذا متوقع. حاول تنصيب بعض الواجهات من [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory]، عن طريق تحميل:\n:* تحميل [https://www.mediawiki.org/wiki/Download tarball installer]، والذي يأتي مع واجهات وامتدادات عديدة. أنت يمكنك نسخ مجلد ال<code>skins/</code> مباشرة منه.\n:* تحميل ال  واجهات الtarballs الفردية من [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins استخدام Git لتحميل الواجهات].\n: فعل هذا ينبغي ألا يتعارض مع مستودع git الخاص بك لو أنك مطور ميدياويكي.\n\n; لو أنك قمت بترقية ميدياويكي حالا:\n: MediaWiki 1.24 وأحدث لم يعد يقوم بتفعيل الواجهات المنصبة تلقائيا (انظر [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). أنت يمكنك نسخ {{PLURAL:$5|السطر التالي|السطور التالية}} إلى <code>LocalSettings.php</code> لتفعيل {{PLURAL:$5||كل}}  {{PLURAL:$5|الواجهة|الواجهات}} المنصبة:\n\n<pre dir=\"ltr\">$3</pre>\n\n; لو أنك قمت بتعديل <code>LocalSettings.php</code> حالا:\n: فتحقق مجددا من أسماء الواجهات للأخطاء الإملائية.",
+       "default-skin-not-found-no-skins": "أخ! الواجهة الافتراضية للويكي الخاصة بك، والمعرفة في <code>$wgDefaultSkin</code> ك<code>$1</code>، غير متوفرة.\n\nأنت ليس لديك أي واجهات منصبة.\n\n; لو أنك قد قمت بتنصيب أو ترقية ميدياويكي حالا:\n: أنت على الأرجح قد قمت بالتنصيب من git، أو مباشرة من الكود المصدري باستخدام طريقة أخرى. هذا متوقع. MediaWiki 1.24 وأحدث لا يحتوي على أي واجهات في المستودع الرئيسي. حاول تنصيب بعض الواجهات من  [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory]، عن طريق تحميل [https://www.mediawiki.org/wiki/Download tarball installer], والذي يأتي مع واجهات وامتداات عديدة. أنت يمكنك نسخ مجلد ال<code>skins/</code> منه.\n:* تحميل tarballs الواجهات الفردية من [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins استخدام Git لتحميل الواجهات].\n: فعل هذا ينبغي ألا يتداخل مع مستودع git الخاص بك لو أنك مطور ميدياويكي. انظر [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] للمعلومات حول كيفية تفعيل الواجهات واختيار الافتراضي.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (مفعل)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>ملغاة</strong>)",
        "mediastatistics": "إحصاءات الميديا",
        "sessionprovider-nocookies": "قد يتم تعطيل الكوكيز. تأكد من تمكين ملفات تعريف الأرتباط وأبد مرةأخرى.",
        "randomrootpage": "صفحة جذر عشوائية",
        "log-action-filter-block": "نوع المنع:",
+       "log-action-filter-contentmodel": "نوع تغيير موديل المحتوى:",
        "log-action-filter-delete": "نوع الحذف:",
        "log-action-filter-import": "نوع الاستيراد:",
        "log-action-filter-managetags": "نوع فعل إدارة الوسوم:",
        "log-action-filter-move": "نوع النقل:",
        "log-action-filter-newusers": "نوع إنشاء الحساب:",
+       "log-action-filter-patrol": "نوع الخفر:",
        "log-action-filter-protect": "نوع الحماية:",
        "log-action-filter-rights": "نوع تغيير الصلاحية",
+       "log-action-filter-suppress": "نوع الإخفاء:",
        "log-action-filter-upload": "نوع الرفع:",
        "log-action-filter-all": "الكل",
        "log-action-filter-block-block": "منع",
        "log-action-filter-block-reblock": "منع التعديل",
        "log-action-filter-block-unblock": "رفع المنع",
+       "log-action-filter-contentmodel-change": "تغيير موديل المحتوى",
+       "log-action-filter-contentmodel-new": "إنشاء صفحة بموديل محتوى غير قياسي",
        "log-action-filter-delete-delete": "حذف الصفحات",
        "log-action-filter-delete-restore": "استرجاع الصفحات",
        "log-action-filter-delete-event": "حذف السجلات",
        "log-action-filter-delete-revision": "حذف المراجعات",
        "log-action-filter-import-interwiki": "استيراد عابر للويكي",
+       "log-action-filter-import-upload": "استيراد بواسطة رفع XML",
        "log-action-filter-managetags-create": "إنشاء الوسوم",
        "log-action-filter-managetags-delete": "حذف الوسوم",
+       "log-action-filter-managetags-activate": "تفعيل الوسم",
+       "log-action-filter-managetags-deactivate": "تعطيل الوسم",
+       "log-action-filter-move-move": "نقل بدون الكتابة على التحويلات",
+       "log-action-filter-move-move_redir": "نقل مع الكتابة على التحويلات",
+       "log-action-filter-newusers-create": "إنشاء بواسطة مستخدم مجهول",
+       "log-action-filter-newusers-create2": "إنشاء بواسطة مستخدم مسجل",
        "log-action-filter-newusers-autocreate": "إنشاء آلي",
        "log-action-filter-newusers-byemail": "الإنشاء بكلمة مرور مرسلة عبر البريد الإلكتروني",
+       "log-action-filter-patrol-patrol": "خفر يدوي",
+       "log-action-filter-patrol-autopatrol": "خفر أوتوماتيكي",
        "log-action-filter-protect-protect": "حماية",
        "log-action-filter-protect-modify": "تعديل الحماية",
        "log-action-filter-protect-unprotect": "رفع الحماية",
+       "log-action-filter-protect-move_prot": "نقل الحماية",
        "log-action-filter-rights-rights": "تغيير يدوي",
+       "log-action-filter-rights-autopromote": "تغيير أوتوماتيكي",
+       "log-action-filter-suppress-event": "إخفاء السجل",
+       "log-action-filter-suppress-revision": "إخفاء المراجعة",
+       "log-action-filter-suppress-delete": "إخفاء الصفحة",
+       "log-action-filter-suppress-block": "إخفاء المستخدم بواسطة المنع",
+       "log-action-filter-suppress-reblock": "إخفاء المستخدم بواسطة إعادة المنع",
        "log-action-filter-upload-upload": "رفع جديد",
        "log-action-filter-upload-overwrite": "إعادة الرفع",
+       "authmanager-authn-not-in-progress": "عملية التحقق ليست جارية أو بينات الجلسة تم فقدها. من فضلك ابدأ مرة ثانية من البداية.",
+       "authmanager-authn-no-primary": "الاعتماد الموفر لم يمكن التحقق منه.",
+       "authmanager-authn-no-local-user": "الاعتماد الموفر غير مرتبط بأي مستخدم على هذه الويكي.",
+       "authmanager-authn-no-local-user-link": "الاعتمادات الموفرة صحيحة لكن غير مرتبطة بأي مستخدم على هذه الويكي. سجل الدخول باستخدام طريقة أخرى، أو أنشيء مستخدما جديدا، وستمتلك الاختيار لوصل اعتماداتك السابقة لذلك الحساب.",
+       "authmanager-authn-autocreate-failed": "الإنشاء التلقائي لحساب محلي فشل: $1",
+       "authmanager-change-not-supported": "الاعتمادات الموفرة لم يمكن تغييرها، حيث أن لا شيء سيستخدمها.",
        "authmanager-create-disabled": "إنشاء الحسابات معطل.",
        "authmanager-create-from-login": "لإنشاء حساب، برجاء ملء الحقول أدناه.",
+       "authmanager-create-not-in-progress": "إنشاء الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية من البداية.",
+       "authmanager-create-no-primary": "الاعتمادات الموفرة لم يمكن استخدامها لإنشاء الحساب.",
+       "authmanager-link-no-primary": "الاعتماد الموفر لم يمكن استخدامه لوصل الحسابات.",
+       "authmanager-link-not-in-progress": "وصل الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية منذ البداية.",
+       "authmanager-authplugin-setpass-failed-title": "تغيير كلمة السر فشل",
+       "authmanager-authplugin-setpass-failed-message": "إضافة التحقق رفضت تغيير كلمة السر.",
+       "authmanager-authplugin-create-fail": "إضافة التحقق رفضت إنشاء الحساب.",
+       "authmanager-authplugin-setpass-denied": "إضافة التحقق لا تسمح بتغيير كلمات السر.",
+       "authmanager-authplugin-setpass-bad-domain": "نطاق غير صحيح.",
+       "authmanager-autocreate-noperm": "إنشاء الحساب التلقائي غير مسموح به.",
+       "authmanager-autocreate-exception": "إنشاء الحسابات التلقائي تم تعطيله مؤقتا نظرا للأخطاء السابقة.",
+       "authmanager-userdoesnotexist": "حساب المستخدم \"$1\" غير مسجل.",
+       "authmanager-userlogin-remembermypassword-help": "ما إذا كانت كلمة السر ينبغي أن يتم تذكرها لأطول من مدة الجلسة.",
+       "authmanager-username-help": "اسم المستخدم للتوثيق.",
+       "authmanager-password-help": "كلمة السر للتوثيق",
+       "authmanager-domain-help": "النطاق للتوثيق الخارجي.",
        "authmanager-retype-help": "كلمة المرور مرة أخرى للتأكيد.",
        "authmanager-email-label": "البريد الإلكتروني",
        "authmanager-email-help": "عنوان البريد الإلكتروني",
        "authmanager-provider-password": "توثيق مبني على كلمة المرور",
        "authmanager-provider-password-domain": "توثيق مبني على كلمة المرور والنطاق",
        "authmanager-provider-temporarypassword": "كلمة مرور مؤقتة",
+       "authprovider-confirmlink-message": "بناء على محاولات تسجيل الدخول الحديثة الخاصة بك، فالحسابات التالية يمكن وصلها بحساب الويكي الخاص بك. وصلهم يفعل تسجيل الدخول عبر هذه الحسابات. من فضلك اختر أيهم ينبغي أن يتم وصلها.",
+       "authprovider-confirmlink-request-label": "الحسابات التي ينبغي أن يتم وصلها",
+       "authprovider-confirmlink-success-line": "$1: تم الوصل بشكل صحيح.",
+       "authprovider-confirmlink-failed": "وصل الحساب لم ينجح بشكل كامل: $1",
+       "authprovider-confirmlink-ok-help": "الاستمرار بعد عرض رسائل فشل الوصل.",
        "authprovider-resetpass-skip-label": "تخطى",
        "authprovider-resetpass-skip-help": "تخطي إعادة تعيين كلمة المرور",
+       "authform-nosession-login": "عملية التحقق كانت ناجحة، لكن متصفحك لا يمكنه \"تذكر\" أنك مسجل الدخول.\n\n$1",
+       "authform-nosession-signup": "الحساب تم إنشاؤه، لكن متصفحك لا يمكنه cannot \"تذكر\" أنك مسجل الدخول.\n\n$1",
+       "authform-newtoken": "توكين مفقود. $1",
+       "authform-notoken": "توكين مفقود",
+       "authform-wrongtoken": "توكين خاطئ",
+       "specialpage-securitylevel-not-allowed-title": "غير مسموح به",
+       "specialpage-securitylevel-not-allowed": "عذرا، أنت غير مسموح لك باستخدام هذه الصفة لأن هويتك لا يمكن التحقق منها.",
+       "authpage-cannot-login": "غير قادر على بدء عملية تسجيل الدخول.",
+       "authpage-cannot-login-continue": "غير قادر على الاستمرار في تسجيل الدخول. جلستك على الأرجح انتهت صلاحيتها.",
+       "authpage-cannot-create": "غير قادر على بدء عملية إنشاء الحساب.",
+       "authpage-cannot-create-continue": "غير قادر على الاستمرار في إنشاء الحساب. جلستك على الأرجح انتهت صلاحيتها.",
+       "authpage-cannot-link": "غير قادر على بدء عملية وصل الحسابات.",
+       "authpage-cannot-link-continue": "غير قادر على الاستمرار في وصل الحساب. جلستك على الأرجح انتهت صلاحيتها.",
        "cannotauth-not-allowed-title": "الإذن مرفوض",
+       "cannotauth-not-allowed": "أنت غير مسموح لك باستخدام هذه الصفحة",
        "changecredentials": "تغيير الاعتماد",
        "changecredentials-submit": "تغيير الاعتماد",
+       "changecredentials-invalidsubpage": "$1 ليس نوع اعتماد صحيح.",
+       "changecredentials-success": "اعتماداتك تم تغييرها.",
        "removecredentials": "إزالة الاعتماد",
        "removecredentials-submit": "إزالة الاعتماد",
+       "removecredentials-invalidsubpage": "$1 ليس نوع اعتمادات صحيح.",
+       "removecredentials-success": "اعتماداتك تمت إزالتها.",
+       "credentialsform-provider": "نوع الاعتمادات:",
        "credentialsform-account": "اسم الحساب:",
        "cannotlink-no-provider-title": "لا توجد حسابات قابلة للربط",
        "cannotlink-no-provider": "لا توجد حسابات قابلة للربط",
        "linkaccounts": "ربط الحسابات",
+       "linkaccounts-success-text": "الحساب تم وصله.",
        "linkaccounts-submit": "اربط الحسابات",
-       "unlinkaccounts": "إزالة ربط الحسابات"
+       "unlinkaccounts": "إزالة ربط الحسابات",
+       "unlinkaccounts-success": "الحساب تم فك وصله.",
+       "authenticationdatachange-ignored": "تغيير بيانات التحقق لم يتم التعامل معه. ربما لم يتم ضبط موفر؟",
+       "userjsispublic": "من فضلك لاحظ: صفحات الجافاسكريبت الفرعية لا ينبغي أن تحتوي غلى بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين.",
+       "usercssispublic": "من فضل لاحظ: صفحات الCSS الفرعية لا ينبغي أن تحتوي على بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين."
 }
index 3432c23..add8bea 100644 (file)
        "delete-confirm": "Silinən səhifə: \"$1\"",
        "delete-legend": "Sil",
        "historywarning": "'''Xəbərdarlıq:''' Silinəcək səhifənin tarixçəsində qeyd olunmuş $1 {{PLURAL:$1|redaktə|redaktə}} var:",
+       "historyaction-submit": "Göstər",
        "confirmdeletetext": "Bu səhifə və ya fayl bütün tarixçəsi ilə birlikdə birdəfəlik silinəcək. Bunu [[{{MediaWiki:Policy-url}}|qaydalara]] uyğun etdiyinizi və əməliyyatın nəticələrini başa düşdüyünüzü təsdiq edin.",
        "actioncomplete": "Fəaliyyət tamamlandı",
        "actionfailed": "Əməliyyat yerinə yetirilmədi",
index 1a537ce..76c2859 100644 (file)
        "userlogin-loggedin": "سیر حال حاضیردا {{GENDER:$1|$1}} عونوانیندا گیریش ائدیب سیز.\nآشاغیداکی فورمودان بیر آیری ایشلدن عونوانیندا گیریش اوچون ایشلدین.",
        "userlogin-reauth": "{{GENDER:$1|$1}} اوْلدوغونوزو تأیید ائتمک اۆچون یئنه گیرمه‌لیسینیز.",
        "userlogin-createanother": "بیر باشقا حساب یارات",
-       "createacct-emailrequired": "ایمیل آدرسی",
+       "createacct-emailrequired": "ایمئیل آدرسی",
        "createacct-emailoptional": "ایمیل آدرسی (ایستگه باغلی)",
        "createacct-email-ph": "ایمیل آدرسینیزی یازین",
        "createacct-another-email-ph": "ایمیل آدرسینیزی یازین",
index 51f186e..1dfc717 100644 (file)
        "passwordreset-emaildisabled": "Функцыі электроннай пошты ў гэтай вікі былі адключаныя.",
        "passwordreset-username": "Імя ўдзельніка:",
        "passwordreset-domain": "Дамэн:",
-       "passwordreset-capture": "Ð\9fаказаÑ\86Ñ\8c ÐºÐ°Ð½Ñ\87аÑ\82ковы электронны ліст?",
-       "passwordreset-capture-help": "Калі Вы пазначыце гэтае поле, электронны ліст (з часовым паролем), будзе паказаны Вам як толькі ён будзе дасланы ўдзельніку.",
+       "passwordreset-capture": "Ð\9fаказаÑ\86Ñ\8c Ð²Ñ\8bнÑ\96ковы электронны ліст?",
+       "passwordreset-capture-help": "Калі Вы пазначыце гэтае поле, электронны ліст (з часовым паролем) будзе паказаны Вам, як толькі ён будзе дасланы ўдзельніку.",
        "passwordreset-email": "Адрас электроннай пошты:",
        "passwordreset-emailtitle": "Падрабязнасьці рахунку ў {{GRAMMAR:месны|{{SITENAME}}}}",
        "passwordreset-emailtext-ip": "Нехта (магчыма Вы, з IP-адрасу $1) зрабіў запыт на скіданьне вашага паролю ў {{GRAMMAR:месны|{{SITENAME}}}} ($4). {{PLURAL:$3|1=Наступны рахунак удзельніка зьвязаны|Наступныя рахункі ўдзельнікаў зьвязаныя}} з гэтым адрасам электроннай пошты:\n\n$2\n\n{{PLURAL:$3|1=Гэты часовы пароль будзе|Гэтыя часовыя паролі будуць}} дзейнічаць $5 {{PLURAL:$5|дзень|дні|дзён}}.\nЦяпер Вам неабходна ўвайсьці і выбраць новы пароль. Калі нехта іншы зрабіў гэты запыт, ці Вы ўспомнілі Ваш пачатковы пароль, які ня хочаце мяняць, Вы можаце праігнараваць гэтае паведамленьне, і працягваць выкарыстоўваць стары пароль.",
        "watchnologin": "Вы не ўвайшлі ў сыстэму",
        "addwatch": "Дадаць ў сьпіс назіраньня",
        "addedwatchtext": "Старонка «[[:$1]]» і яе старонка абмеркаваньня былі дададзеная да Вашага [[Special:Watchlist|сьпісу назіраньня]].",
+       "addedwatchtext-talk": "«[[:$1]]» і зьвязаная зь ёй старонка дададзеныя да вашага [[Special:Watchlist|сьпісу назіраньня]].",
        "addedwatchtext-short": "Старонка «$1» была дададзеная ў ваш сьпіс назіраньня.",
        "removewatch": "Выдаліць са сьпісу назіраньня",
        "removedwatchtext": "Старонка «[[:$1]]» і яе старонка абмеркаваньня былі выдаленыя з Вашага [[Special:Watchlist|сьпісу назіраньня]].",
+       "removedwatchtext-talk": "«[[:$1]]» і зьвязаная зь ёй старонка выдаленыя з вашага [[Special:Watchlist|сьпісу назіраньня]].",
        "removedwatchtext-short": "Старонка «$1» была выдаленая з вашага сьпісу назіраньня.",
        "watch": "Назіраць",
        "watchthispage": "Назіраць за гэтай старонкай",
        "rollbacklinkcount-morethan": "адкаціць больш за $1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "rollbackfailed": "Памылка адкату",
        "rollback-missingparam": "У запыце адсутнічаюць абавязковыя парамэтры.",
+       "rollback-missingrevision": "Не атрымалася загрузіць зьвесткі вэрсіі.",
        "cantrollback": "Немагчыма адкаціць зьмену; апошні рэдактар — адзіны аўтар гэтай старонкі.",
        "alreadyrolled": "Немагчыма адкаціць апошнюю зьмену [[:$1]], якую {{GENDER:$2|зрабіў|зрабіла}} [[User:$2|$2]] ([[User talk:$2|гутаркі]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); нехта іншы ўжо зьмяніў старонку альбо адкаціў зьмены.\n\nАпошнія зьмены зробленыя [[User:$3|$3]] ([[User talk:$3|гутаркі]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Кароткае апісаньне зьменаў было: <em>$1</em>.",
        "undeletehistorynoadmin": "Гэтая старонка была выдаленая.\nПрычына выдаленьня пададзена ніжэй, разам са зьвесткамі ўдзельніка, які рэдагаваў старонку перад выдаленьнем.\nТэкст выдаленай старонкі могуць глядзець толькі адміністратары.",
        "undelete-revision": "Выдаленая вэрсія $1 (ад $5 $4) ўдзельніка $3:",
        "undeleterevision-missing": "Некарэктная ці неіснуючая вэрсія.\nВерагодна Вы карысталіся няслушнай спасылкай, альбо, магчыма, вэрсія была выдаленая з архіву.",
+       "undeleterevision-duplicate-revid": "$1 {{PLURAL:$1|вэрсія ня можа быць адноўленая|вэрсіі ня могуць быць адноўленыя|вэрсіяў ня могуць быць адноўленыя}}, бо {{PLURAL:$1|1=яе|іх}} <code>rev_id</code> ужо выкарыстоўваецца.",
        "undelete-nodiff": "Папярэдняя вэрсія ня знойдзеная.",
        "undeletebtn": "Аднавіць",
        "undeletelink": "паглядзець/аднавіць",
        "log-action-filter-delete-restore": "Аднаўленьне старонкі",
        "log-action-filter-delete-event": "Выдаленьне журналу",
        "log-action-filter-delete-revision": "Выдаленьне вэрсіі",
-       "log-action-filter-managetags-create": "Стварэньне цэтлікаў",
-       "log-action-filter-managetags-delete": "Выдаленьне цэтлікаў",
-       "log-action-filter-managetags-activate": "Актывацыя цэтлікаў",
-       "log-action-filter-managetags-deactivate": "Дэактывацыя цэтлікаў",
+       "log-action-filter-managetags-create": "Стварэньне метак",
+       "log-action-filter-managetags-delete": "Выдаленьне метак",
+       "log-action-filter-managetags-activate": "Актывацыя метак",
+       "log-action-filter-managetags-deactivate": "Дэактывацыя метак",
        "log-action-filter-newusers-autocreate": "Аўтаматычнае стварэньне",
        "log-action-filter-patrol-autopatrol": "Аўтаматычнае патруляваньне",
        "log-action-filter-protect-protect": "Абарона",
index 42348b0..f0c9999 100644 (file)
        "passwordreset-emailsentemail": "Калі гэты адрас электроннай пошты злучаны з вашым уліковым запісам, будзе адпраўлены ліст пра скід пароля.",
        "passwordreset-emailsentusername": "Калі ёсць адрас электроннай пошты, злучаны з гэтым імем удзельніка, то будзе дасланы ліст пра скід пароля.",
        "passwordreset-emailsent-capture2": "{{PLURAL:$1|Электронны ліст|электронныя лісты}} скіду пароля адпраўлены. {{PLURAL:$1|Імя ўдзельніка і пароль|Спіс імён удзельнікаў і паролі}} паказаны ніжэй.",
+       "passwordreset-emailerror-capture2": "Не ўдалося даслаць {{GENDER:$2|удзельніку|удзельніцы}} ліст электроннай поштай: $1 {{PLURAL:$3|Імя ўдзельніка і пароль|Спіс імён удзельнікаў і паролі}} паказаны ніжэй.",
+       "passwordreset-nocaller": "Мусіць быць указана, хто выклікае",
+       "passwordreset-nosuchcaller": "Аўтар выкліку не існуе: $1",
        "passwordreset-invalideamil": "Няслушны адрас электроннай пошты",
        "passwordreset-nodata": "Не былі пададзены ні імя ўдзельніка, ні адрас электроннай пошты",
        "changeemail": "Змяніць або выдаліць адрас электроннай пошты",
index 41d32b5..c8eb76b 100644 (file)
@@ -54,6 +54,7 @@
        "tog-watchdefault": "Добавяне на страниците, които редактирам, в списъка ми за наблюдение",
        "tog-watchmoves": "Добавяне на преместените от мен страници и файлове към списъка ми за наблюдение",
        "tog-watchdeletion": "Добавяне на изтритите от мен страници и файлове към списъка ми за наблюдение",
+       "tog-watchuploads": "Добавяне на новите качени от мен файлове към списъка ми за наблюдение",
        "tog-watchrollback": "Добавяне на страници, в които съм {{GENDER:$1|извършвал|извършвала}} отмяна на редакции в списъка ми за наблюдениe",
        "tog-minordefault": "Отбелязване на всички промени като малки по подразбиране",
        "tog-previewontop": "Показване на предварителния преглед преди текстовата кутия",
        "history-feed-description": "Редакционна история на страницата в {{SITENAME}}",
        "history-feed-item-nocomment": "$1 в $2",
        "history-feed-empty": "Исканата страница не съществува — може да е била изтрита или преименувана. Опитайте да [[Special:Search|потърсите]] нови страници, които биха могли да са ви полезни.",
+       "history-edit-tags": "Редактиране етикетите на избраните редакции",
        "rev-deleted-comment": "(резюмето е премахнато)",
        "rev-deleted-user": "(името на автора е изтрито)",
        "rev-deleted-event": "(записът е изтрит)",
        "revdelete-unsuppress": "Премахване на ограниченията за възстановените версии",
        "revdelete-log": "Причина:",
        "revdelete-submit": "Прилагане към {{PLURAL:$1|избраната версия|избраните версии}}",
-       "revdelete-success": "'''Видимостта на версията беше променена успешно.'''",
+       "revdelete-success": "Видимостта на версията беше променена успешно.",
        "revdelete-failure": "'''Видимостта на редакцията не може да бъде обновена:'''\n$1",
        "logdelete-success": "Видимостта на дневника е установена.",
        "logdelete-failure": "'''Видимостта на дневника не може да бъде променяна:'''\n$1",
        "mergehistory-go": "Показване на редакциите, които могат да се слеят",
        "mergehistory-submit": "Сливане на редакции",
        "mergehistory-empty": "Няма редакции, които могат да бъдат слети.",
-       "mergehistory-done": "$3 {{PLURAL:$3|версия|версии}} от $1 бяха успешно слети с редакционната история на [[:$2]].",
+       "mergehistory-done": "$3 {{PLURAL:$3|версия|версии}} от $1 {{PLURAL:$3|беше успешно слята|бяха успешно слети}} с редакционната история на [[:$2]].",
        "mergehistory-fail": "Невъзможно е да се извърши сливане на редакционните истории; проверете страницата и времевите параметри.",
        "mergehistory-no-source": "Изходната страница $1 не съществува.",
        "mergehistory-no-destination": "Целевата страница $1 не съществува.",
        "userrights": "Управление на потребителските права",
        "userrights-lookup-user": "Управляване на потребителските групи",
        "userrights-user-editname": "Потребителско име:",
-       "editusergroup": "Редактиране на потребителските групи",
-       "editinguser": "Промяна на потребителските права на потребител '''[[User:$1|$1]]''' $2",
+       "editusergroup": "Редактиране на {{GENDER:$1|потребителските}} групи",
+       "editinguser": "Промяна на потребителските права на {{GENDER:$1|потребител }} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Редактиране на потребителските групи",
        "saveusergroups": "Съхраняване на потребителските групи",
        "userrights-groupsmember": "Член на:",
        "right-ipblock-exempt": "пренебрегване на блокирания по IP blocks, автоматични блокирания и блокирани IP интервали",
        "right-unblockself": "Собствено отблокиране",
        "right-protect": "променяне на нивото на защита и редактиране на защитени страници",
-       "right-editprotected": "редактиране на защитени страници (без каскадна защита)",
+       "right-editprotected": "Редактиране на страници защитени като „{{int:protect-level-sysop}}“",
        "right-editinterface": "Редактиране на потребителския интерфейс",
        "right-editusercssjs": "редактиране на CSS и JS файловете на други потребители",
        "right-editusercss": "редактиране на CSS файловете на други потребители",
index aa81ac2..19e709f 100644 (file)
        "sectioneditnotsupported-text": "এই সম্পাদনা পাতায় অনুচ্ছেদ সম্পাদনা সমর্থন করে না",
        "permissionserrors": "অনুমতি ত্রুটিসমূহ",
        "permissionserrorstext": "আপনার এটা করার অনুমতি নেই, নিচের {{PLURAL:$1|টি কারণের|টি কারণের}} জন্য:",
-       "permissionserrorstext-withaction": "à¦\86পনার $2 à¦\95রার à¦\85নà§\81মতি à¦¨à§\87à¦\87, à¦¯à¦¾à¦° {{PLURAL:$1|à¦\95ারণ|à¦\95ারণসমà§\82হ}} à¦¹à¦²:",
+       "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণ|কারণসমূহ}} হল:",
        "recreate-moveddeleted-warn": "'''সতর্কীকরণ: আপনি এমন একটি পাতা পুনরায় তৈরি করছেন যা পূর্বে অপসারণ করা হয়েছিল।'''\n\nআপনি পাতাটি সম্পাদনা চালিয়ে যাওয়া ঠিক হবে কিনা, তা বিবেচনা করুন।\nআপনার সুবিধার্থে পাতাটির অপলুপ্তি লগ এখানে দেয়া হলো:",
        "moveddeleted-notice": "এই পাতাটি অপসারণ করা হয়েছে।\nসূত্র হিসেবে নিচে এ পাতার অবলুপ্তি লগ দেওয়া হলো।",
        "moveddeleted-notice-recent": "দুঃখিত, এই পাতাটি সাম্প্রতি অপসারিত হয়েছে (সর্বশেষ ২৪ ঘণ্টায়)।\nসূত্র হিসেবে নিচে এই পাতা অপসারণ ও স্থানান্তর লগ দেয়া হয়েছে।",
        "newuserlogpagetext": "এটি নতুন ব্যবহারকারী সৃষ্টির লগ",
        "rightslog": "ব্যবহারকারীর অধিকার লগ",
        "rightslogtext": "এটি ব্যবহারকারী অধিকারে আনা পরিবর্তনগুলির একটি লগ।",
-       "action-read": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦ªà¦¡à¦¼à§\81ন",
-       "action-edit": "এই পাতাটি সম্পাদনা",
-       "action-createpage": "এই পাতাটি তৈরি",
-       "action-createtalk": "এই আলাপের পাতাটি তৈরি",
-       "action-createaccount": "à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\8fà¦\95াà¦\89নà§\8dà¦\9fà¦\9fি à¦¤à§\88রি à¦\95রà§\8b",
-       "action-history": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦\87তিহাস à¦¦à§\87à¦\96াà¦\93",
-       "action-minoredit": "à¦\8fà¦\87 à¦¸à¦®à§\8dপাদনাà¦\9fি à¦\85নà§\81লà§\8dলà§\87à¦\96à§\8dয à¦¹à¦¿à¦¸à§\87বà§\87 à¦\9aিহà§\8dনিত à¦\95রà§\8b",
+       "action-read": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦ªà¦¡à¦¼à¦¾à¦°",
+       "action-edit": "এই পাতাটি সম্পাদনা করার",
+       "action-createpage": "এই পাতাটি তৈরি করার",
+       "action-createtalk": "এই আলাপ পাতাটি তৈরি করার",
+       "action-createaccount": "à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\8fà¦\95াà¦\89নà§\8dà¦\9fà¦\9fি à¦¤à§\88রি à¦\95রার",
+       "action-history": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦\87তিহাস à¦¦à§\87à¦\96ার",
+       "action-minoredit": "à¦\8fà¦\87 à¦¸à¦®à§\8dপাদনাà¦\9fি à¦\85নà§\81লà§\8dলà§\87à¦\96à§\8dয à¦¹à¦¿à¦¸à§\87বà§\87 à¦\9aিহà§\8dনিত à¦\95রার",
        "action-move": "পাতাটি সরিয়ে ফেলুন",
        "action-move-subpages": "পাতাটি এবং এর উপপাতাগুলো সরিয়ে ফেলুন",
        "action-move-rootuserpages": "root ব্যবহারকারীর পাতাগুলো সরিয়ে ফেলুন",
        "action-move-categorypages": "বিষয়শ্রেণী পাতাসমূহ স্থানান্তর করুন",
-       "action-movefile": "এই ফাইলটি সরিয়ে ফেলুন",
-       "action-upload": "à¦\8fà¦\87 à¦«à¦¾à¦\87ল à¦\86পলà§\8bড à¦\95রà§\8b",
+       "action-movefile": "এই ফাইল স্থানান্তর করার",
+       "action-upload": "à¦\8fà¦\87 à¦«à¦¾à¦\87ল à¦\86পলà§\8bড à¦\95রার",
        "action-reupload": "বিদ্যমান ফাইল প্রতিস্থাপন করো",
-       "action-reupload-shared": "শà§\87য়ারà§\8dড à¦°à¦¿à¦ªà§\8bà¦\9cিà¦\9fরà§\80তà§\87 à¦\8fà¦\87 à¦«à¦¾à¦\87লà¦\9fি à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রà§\81ন",
+       "action-reupload-shared": "শà§\87য়ারà§\8dড à¦°à¦¿à¦ªà§\8bà¦\9cিà¦\9fরà§\80তà§\87 à¦\8fà¦\87 à¦«à¦¾à¦\87লà¦\9fি à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রার",
        "action-upload_by_url": "কোন ইউআরএল থেকে ফাইলটি আপলোড করো",
        "action-writeapi": "রাইট এপিআই ব্যবহার করুন",
        "action-delete": "পাতাটি মুছে ফেলো",
-       "action-deleterevision": "à¦\8fà¦\87 à¦¸à¦\82শà§\8bধনà¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লà§\8b",
+       "action-deleterevision": "à¦\8fà¦\87 à¦¸à¦\82শà§\8bধনà¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লার",
        "action-deletedhistory": "পাতার মুছে ফেলা ইতিহাস দেখাও",
        "action-browsearchive": "অপসারিত পাতায় অনুসন্ধান করুন",
        "action-undelete": "পাতাটি পুনরুদ্ধার করো",
        "action-suppressrevision": "লুকানো সংস্করণগুলো পর্যালোচনা এবং পুনঃস্থাপন করুন",
-       "action-suppressionlog": "à¦\8fà¦\87 à¦¬à§\8dযà¦\95à§\8dতিà¦\97ত à¦²à¦\97 à¦¦à§\87à¦\96াà¦\93",
-       "action-block": "à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80à¦\95à§\87 à¦¸à¦®à§\8dপাদনা à¦\95রতà§\87 à¦¬à¦¾à¦\81ধা à¦¦à¦¾à¦\93",
-       "action-protect": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à§\81রà¦\95à§\8dষার à¦®à¦¾à¦¤à§\8dরা à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রà§\8b",
+       "action-suppressionlog": "à¦\8fà¦\87 à¦¬à§\8dযà¦\95à§\8dতিà¦\97ত à¦²à¦\97 à¦¦à§\87à¦\96ার",
+       "action-block": "à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80à¦\95à§\87 à¦¸à¦®à§\8dপাদনা à¦\95রতà§\87 à¦¬à¦¾à¦\81ধা à¦¦à§\87য়ার",
+       "action-protect": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦¸à§\81রà¦\95à§\8dষার à¦®à¦¾à¦¤à§\8dরা à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রার",
        "action-rollback": "একটি নির্দিষ্ট পাতার সর্বশেষ ব্যবহারকারীর সম্পদনা পূর্বাবস্থায় ফিরিয়ে আনুন",
        "action-import": "অন্য উইকি থেকে পাতা আমদানী করো",
        "action-importupload": "ফাইল আপলোড থেকে পাতা আমদানী করো",
        "action-patrol": "অন্যদের সম্পাদনা পরীক্ষিত বলে চিহ্নিত করো",
        "action-autopatrol": "পরীক্ষিত বলে চিহ্নিত কি আপনি সম্পাদনা করেছেন",
        "action-unwatchedpages": "নজরতালিকা বহির্ভূত পাতাগুলির তালিকা দেখাও",
-       "action-mergehistory": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦\87তিহাস à¦\8fà¦\95তà§\8dরিত à¦\95রà§\81ন",
+       "action-mergehistory": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦\87তিহাস à¦\8fà¦\95তà§\8dরিত à¦\95রার",
        "action-userrights": "সকল ব্যবহারকারীর অধিকার সম্পাদনা করুন",
        "action-userrights-interwiki": "অন্যান্য উইকির ব্যবহারকারীদের অধিকারসমূহ সম্পাদনা করুন",
        "action-siteadmin": "ডাটাবেজ বন্ধ অথবা খুলুন",
        "action-managechangetags": "ট্যাগ তৈরি ও সক্রিয়/নিষ্ক্রিয়",
        "action-applychangetags": "আপনার পরিবর্তনগুলোর সাথে ট্যাগ সংযোজন করুন",
        "action-changetags": "নির্দিষ্ট সংস্করণ এবং দীর্ঘ সম্পাদনাগুলোতে ট্যাগ সংযোজন ও অপসারণ করুন",
-       "action-purge": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾ à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রà§\81ন",
+       "action-purge": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾ à¦¹à¦¾à¦²à¦¨à¦¾à¦\97াদ à¦\95রার",
        "nchanges": "$1টি {{PLURAL:$1|পরিবর্তন}}",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|সর্বশেষ প্রদর্শনের পর}} $1টি",
        "enhancedrc-history": "ইতিহাস",
        "removecredentials-success": "আপনার পরিচয়পত্র সরানো হয়েছে।",
        "credentialsform-provider": "পরিচয়পত্রের ধরন:",
        "credentialsform-account": "অ্যাকাউন্টের নাম:",
-       "linkaccounts": "অ্যাকাউন্ট সংযোগ করুন"
+       "linkaccounts": "অ্যাকাউন্ট সংযোগ করুন",
+       "userjsispublic": "অনুগ্রহ করে লক্ষ্য করুন: জাভাস্ক্রিপ্টের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।",
+       "usercssispublic": "অনুগ্রহ করে লক্ষ্য করুন: সিএসএসের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।"
 }
index 8c3c3d8..e631f1c 100644 (file)
        "october-date": "$1 a viz Here",
        "november-date": "$1 a viz Du",
        "december-date": "$1 a viz Kerzu",
+       "period-am": "mintin",
+       "period-pm": "goude-merenn",
        "pagecategories": "{{PLURAL:$1|Rummad |Rummad }}",
        "category_header": "Niver a bennadoù er rummad \"$1\"",
        "subcategories": "Isrummadoù",
        "passwordreset-emailtext-user": "Goulennet en deus an implijer $1 war  {{SITENAME}} e vefe degaset soñj dezhañ eus titouroù e gont evit {{SITENAME}} ($4). Emañ liammet {{PLURAL:$3|ar gont implijer|ar c'hontoù implijer}} da-heul gant ar chomlec'h postel-mañ :\n\n$2\n\nMont a raio da get {{PLURAL:$3|ar ger-tremen da c'hortoz|ar gerioù-tremen da c'hortoz}} a-benn {{PLURAL:$5|un devezh|$5 deiz}}.\nMat e vefe deoc'h kevreañ ha dibab ur ger-tremen nevez bremañ. Mard eo bet goulennet kement-se gant unan bennak all pe m'hoc'h eus soñj eus ho ker-tremen orin ha mar ne fell ket deoc'h e cheñch ken, na daolit ket evezh ouzh ar gemennadenn-mañ ha dalc'hit d'ober gant ho ker-tremen kozh.",
        "passwordreset-emailelement": "Anv implijer :           \n$1\n\nGer-tremen da c'hortoz : \n$2",
        "passwordreset-emailsentemail": "Kaset ez eus bet ur postel deoc'h da adderaouekaat ho ker-tremen.",
-       "passwordreset-emailsent-capture": "Ur postel evit aderaouekaat ho ker-tremen, evel diskouezet amañ dindan, zo bet kaset.",
-       "passwordreset-emailerror-capture": "Kaset ez eus bet ur postel degas da soñj evel m'emañ diskouezet amañ dindan met c'hwitet eo bet ar gasadenn d'an {{GENDER:$2|implijer|implijerez}} : $1",
        "changeemail": "Kemmañ ar chomlec'h postel",
        "changeemail-header": "Kemmañ chomlec'h postel ar gont",
        "changeemail-no-info": "Ret eo deoc'h bezañ kevreet a-benn mont d'ar bajenn-se war-eeun.",
        "undo-nochange": "War a seblant eo bet nullet ar c'hemm dija.",
        "undo-summary": "Dizober kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])",
        "undo-summary-username-hidden": "Dizober ar reizhadenn $1 gant un implijer kuzhet",
-       "cantcreateaccounttitle": "Dibosupl krouiñ ar gont",
        "cantcreateaccount-text": "Stanket eo bet ar c'hrouiñ kontoù adal ar chomlec'h IP ('''$1''') gant [[User:$3|$3]].\n\nAn abeg roet gant $3 zo ''$2''",
        "viewpagelogs": "Gwelet ar marilhoù evit ar bajenn-mañ",
        "nohistory": "Ar bajenn-mañ n'he deus tamm istor ebet.",
        "mostrevisions": "Pennadoù bet kemmet ar muiañ",
        "prefixindex": "An holl bajennoù a grog gant...",
        "prefixindex-namespace": "An holl bajennoù enno ur rakger (esaouenn anv $1)",
+       "prefixindex-submit": "Diskouez",
        "prefixindex-strip": "Lemel ar rakger er roll",
        "shortpages": "Pennadoù berr",
        "longpages": "Pennadoù hir",
        "usereditcount": "$1 {{PLURAL:$1|kemm|kemm}}",
        "usercreated": "{{GENDER:$3|Krouet}} d'an $1 da $2",
        "newpages": "Pajennoù nevez",
+       "newpages-submit": "Diskouez",
        "newpages-username": "Anv implijer :",
        "ancientpages": "Pennadoù koshañ",
        "move": "adenvel",
        "apisandbox": "Poull-traezh API",
        "apisandbox-api-disabled": "Diweredekaet eo API war al lec'hienn-mañ.",
        "apisandbox-intro": "Grit gant ar bajenn-mañ evit amprouiñ '''servij Web API MediaWiki'''.\nKit da deuler ur sell war [https://www.mediawiki.org/wiki/API:Main_page titouroù an API] evit gouzout hiroc'h war an doare da embreger API. Da skouer :\n[https://www.mediawiki.org/wiki/API#A_simple_example gwelet danvez ur bennbajenn]. Dibabit un oberiadenn bennak evit gwelet skouerioù all",
+       "apisandbox-unfullscreen": "Diskouez ar bajenn",
        "apisandbox-submit": "Sevel ar goulenn",
        "apisandbox-reset": "Riñsañ",
-       "apisandbox-examples": "Skouer",
-       "apisandbox-results": "Disoc'h",
+       "apisandbox-retry": "Klask en-dro",
+       "apisandbox-examples": "Skouerioù",
+       "apisandbox-dynamic-parameters": "Arventenn ouzhpenn",
+       "apisandbox-dynamic-parameters-add-label": "Ouzhpennañ un arventenn:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Anv an arventenn",
+       "apisandbox-results": "Disoc'hoù",
        "apisandbox-request-url-label": "Goulenn URL :",
        "apisandbox-request-time": "Pad ar goulenn: $1",
        "booksources": "Oberennoù dave",
        "specialloguserlabel": "Implijer :",
        "speciallogtitlelabel": "Bukadenn (titl pe implijer) :",
        "log": "Marilhoù",
+       "logeventslist-submit": "Diskouez",
        "all-logs-page": "An holl varilhoù foran",
        "alllogstext": "Diskwel a-gevret an holl varilhoù hegerz war {{SITENAME}}.\nGallout a rit strishaat ar mod diskwel en ur zibab ar marilh, an anv implijer (diwallit ouzh ar pennlizherennoù) pe ar bajenn a fell deoc'h (memes tra).",
        "logempty": "Goullo eo istor ar bajenn-mañ.",
        "log-title-wildcard": "Klask an titloù a grog gant an destenn-mañ",
        "showhideselectedlogentries": "Diskouez/kuzhat penngerioù ar marilh bet diuzet",
+       "checkbox-select": "Diuzañ : $1",
+       "checkbox-all": "An holl",
+       "checkbox-none": "Hini ebet",
+       "checkbox-invert": "Eilpennañ",
        "allpages": "An holl bajennoù",
        "nextpage": "Pajenn war-lerc'h ($1)",
        "prevpage": "Pajenn gent ($1)",
        "cachedspecial-viewing-cached-ts": "Emaoc'h o sellet ouzh ur stumm krubuilhet eus ar bajenn-mañ a c'hall bezañ dispredet un disterañ.",
        "cachedspecial-refresh-now": "Gwelet an hini nevesañ.",
        "categories": "Roll ar rummadoù",
+       "categories-submit": "Diskouez",
        "categoriespagetext": "Er {{PLURAL:$1|rummad|rummadoù}} da-heul ez eus pajennoù pe restroù media.\nNe ziskouezer ket amañ ar [[Special:UnusedCategories|Rummadoù dizimplij]].\nGwelet ivez ar [[Special:WantedCategories|rummadoù goulennet a vank]].",
        "categoriesfrom": "Diskouez ar rummadoù en ur gregiñ gant :",
        "deletedcontributions": "Degasadennoù diverket un implijer",
        "wlheader-showupdated": "E '''tev''' emañ merket ar pajennoù bet kemmet abaoe ar wezh ziwezhañ hoc'h eus sellet outo",
        "wlnote": "Setu aze {{PLURAL:$1|ar c'hemm diwezhañ|ar '''$1''' kemm diwezhañ}} c'hoarvezet e-kerzh an {{PLURAL:$2|eurvezh|'''$2''' eurvezh}} diwezhañ, d'an $3 da $4.",
        "wlshowlast": "Diskouez an $1 eurvezh $2 devezh diwezhañ",
+       "watchlist-hide": "Kuzhat",
+       "watchlist-submit": "Diskouez",
+       "wlshowhideminor": "kemmoù dister",
+       "wlshowhidebots": "robotoù",
+       "wlshowhideliu": "implijerien enrollet",
+       "wlshowhideanons": "implijerien dizanv",
        "wlshowhidemine": "ma c'hemmoù",
        "watchlist-options": "Dibarzhioù ar roll evezhiañ",
        "watching": "Heuliet...",
        "whatlinkshere-hidelinks": "$1 liamm",
        "whatlinkshere-hideimages": "$1 ar restroù liammet",
        "whatlinkshere-filters": "Siloù",
+       "whatlinkshere-submit": "Mont",
        "autoblockid": "Emstankañ #$1",
        "block": "Stankañ an implijer",
        "unblock": "Distankañ an implijer",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|adweladenn}} enporzhiet eus $2",
        "javascripttest": "Amprouadenn JavaScript",
        "javascripttest-qunit-intro": "Sellet ouzh [$1 an teulioù amprouiñ] e mediawiki.org.",
-       "tooltip-pt-userpage": "Ho pajenn implijer",
+       "tooltip-pt-userpage": "{{GENDER:|Ho pajenn}} implijer",
        "tooltip-pt-anonuserpage": "Ar bajenn implijer evit ar c'homlec'h IP implijet ganeoc'h",
-       "tooltip-pt-mytalk": "Ho pajenn gaozeal",
+       "tooltip-pt-mytalk": "{{GENDER:|Ho}} pajenn gaozeal",
        "tooltip-pt-anontalk": "Kaozeadennoù diwar-benn ar c'hemmoù graet adal ar chomlec'h-mañ",
-       "tooltip-pt-preferences": "Ma fenndibaboù",
+       "tooltip-pt-preferences": "{{GENDER:|Ma}} fenndibaboù",
        "tooltip-pt-watchlist": "Roll ar pajennoù evezhiet ganeoc'h.",
-       "tooltip-pt-mycontris": "Roll ho tegasadennoù",
+       "tooltip-pt-mycontris": "Roll ho tegasadennoù{{GENDER:|your}}",
        "tooltip-pt-login": "Daoust ma n'eo ket ret, ec'h aliomp deoc'h kevreañ",
        "tooltip-pt-logout": "Digevreañ",
        "tooltip-pt-createaccount": "Erbedet eo deoc'h krouiñ ur gont ha kevreañ ; n'eo ket ret koulskoude.",
        "tooltip-t-recentchangeslinked": "Roll ar c'hemmoù diwezhañ war ar pajennoù liammet ouzh ar bajenn-mañ",
        "tooltip-feed-rss": "Magañ ar red RSS evit ar bajenn-mañ",
        "tooltip-feed-atom": "Magañ ar red Atom evit ar bajenn-mañ",
-       "tooltip-t-contributions": "Gwelet roll degasadennoù an implijer-mañ",
+       "tooltip-t-contributions": "Gwelet roll degasadennoù {{GENDER:$1|this user}} an implijer-mañ",
        "tooltip-t-emailuser": "Kas ur postel d'an implijer-mañ",
        "tooltip-t-upload": "Enporzhiañ ur skeudenn pe ur restr media war ar servijer",
        "tooltip-t-specialpages": "Roll an holl bajennoù dibar",
        "tooltip-ca-nstab-category": "Gwelet pajenn ar rummad",
        "tooltip-minoredit": "Merkañ ar c'hemm-mañ evel dister",
        "tooltip-save": "Enrollañ ho kemmoù",
+       "tooltip-publish": "Embann ho kemmoù",
        "tooltip-preview": "Rakwelet ar c'hemmoù; trugarez d'ober gantañ a-raok enrollañ!",
        "tooltip-diff": "Diskouez ar c'hemmoù degaset ganeoc'h en destenn.",
        "tooltip-compareselectedversions": "Sellet ouzh an diforc'hioù zo etre daou stumm diuzet ar bajenn-mañ.",
        "confirm-watch-top": "Ouzhpennañ ar bajenn-mañ d'ho roll evezhiañ",
        "confirm-unwatch-button": "Mat eo",
        "confirm-unwatch-top": "Lemel ar bajenn-mañ a-ziwar ho roll evezhiañ",
+       "confirm-rollback-button": "Mat eo",
        "quotation-marks": "« $1 »",
        "imgmultipageprev": "&larr; pajenn gent",
        "imgmultipagenext": "pajenn war-lerc'h &rarr;",
        "iranian-calendar-m11": "11vet miz Jalāli",
        "iranian-calendar-m12": "12vet miz Jalāli",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|kaozeal]])",
+       "timezone-local": "Lec'hel",
        "duplicate-defaultsort": "Diwallit : Frikañ a ra an alc'hwez dre ziouer \"$2\" an hini a oa a-raok \"$1\".",
        "version": "Stumm",
        "version-extensions": "Astennoù staliet",
        "tags-source-header": "Mammenn",
        "tags-active-header": "Oberiant ?",
        "tags-hitcount-header": "Kemmoù balizennet",
+       "tags-actions-header": "Oberoù",
        "tags-active-yes": "Ya",
        "tags-active-no": "Ket",
        "tags-edit": "aozañ",
        "special-characters-group-thai": "Thai",
        "special-characters-group-lao": "Laoseg",
        "special-characters-group-khmer": "Khmer",
-       "api-error-blacklisted": "Dibabit un titl deskrivañ all",
        "randomrootpage": "Pajenn wrizienn dargouezhek"
 }
index 8e71647..9cafa75 100644 (file)
        "trackingcategories-msg": "Categoria de seguiment",
        "trackingcategories-name": "Nom del missatge",
        "trackingcategories-desc": "Criteris d'inclusió de categoria",
+       "restricted-displaytitle-ignored": "Pàgines amb títols a mostrar ignorats",
        "noindex-category-desc": "La pàgina conté una paraula màgica <code><nowiki>__NOINDEX__</nowiki></code> (i és en un espai de noms on està permesa) i per tant no està indexada per robots.",
        "index-category-desc": "La pàgina conté un <code><nowiki>__INDEX__</nowiki></code> (i és en un espai de noms on està permès) i per tant està indexat per robots quan normalment no ho seria.",
        "post-expand-template-inclusion-category-desc": "La mida de la pàgina és més gran que <code>$wgMaxArticleSize</code> un cop expandides totes les plantilles, per tant algunes plantilles no s'han expandit.",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "rollbacklinkcount-morethan": "reverteix més de $1 {{PLURAL:$1|edició|edicions}}",
        "rollbackfailed": "No s'ha pogut revocar",
+       "rollback-missingrevision": "No es poden carregar les dades de revisió.",
        "cantrollback": "No s'han pogut revertir les edicions; el darrer col·laborador és l'únic autor de la pàgina.",
        "alreadyrolled": "No es pot revertir la darrera modificació de [[:$1]]\nde l'usuari [[User:$2|$2]] ([[User talk:$2|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]). Algú altre ja ha modificat o revertit la pàgina.\n\nLa darrera modificació l'ha fet l'usuari [[User:$3|$3]] ([[User talk:$3|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "El resum d'edició és: <em>$1</em>.",
        "changecontentmodel-success-text": "S'ha canviat el tipus de contingut de [[:$1]].",
        "changecontentmodel-cannot-convert": "El contingut a [[:$1]] no es pot convertir a un tipus de $2.",
        "changecontentmodel-nodirectediting": "El model de contingut $1 no permet l'edició directa",
+       "changecontentmodel-emptymodels-title": "No hi ha models de contingut",
+       "changecontentmodel-emptymodels-text": "El contingut a [[:$1]] no pot convertir-se a cap tipus.",
        "log-name-contentmodel": "Registre de canvis del model de contingut",
        "log-description-contentmodel": "Esdeveniments relacionats amb els models de contingut d'una pàgina",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|ha canviat}} el model de contingut de la pàgina $3 de «$4» a «$5»",
        "lockdbsuccesstext": "S'ha bloquejat la base de dades.<br />\nRecordeu-vos de [[Special:UnlockDB|treure el bloqueig]] quan hàgiu acabat el manteniment.",
        "unlockdbsuccesstext": "S'ha desbloquejat la base de dades del projecte {{SITENAME}}.",
        "lockfilenotwritable": "No es pot modificar el fitxer de la base de dades de bloquejos. Per a blocar o desblocar la base de dades, heu de donar-ne permís de modificació al servidor web.",
+       "databaselocked": "La bases de dades ja està bloquejada.",
        "databasenotlocked": "La base de dades no està bloquejada.",
        "lockedbyandtime": "(per $1 el $2 a les $3)",
        "move-page": "Reanomena $1",
        "redirect-page": "ID de pàgina",
        "redirect-revision": "Revisió de la pàgina",
        "redirect-file": "Nom del fitxer",
+       "redirect-logid": "ID de registre",
        "redirect-not-exists": "No s'ha trobat el valor",
        "fileduplicatesearch": "Cerca fitxers duplicats",
        "fileduplicatesearch-summary": "Cerca fitxers duplicats d'acord amb el seu valor de resum.",
        "tags-edit-title": "Modifica les etiquetes",
        "tags-edit-manage-link": "Gestiona les etiquetes",
        "tags-edit-revision-selected": "{{PLURAL:$1|Revisió seleccionada|Revisions seleccionades}} de [[:$2]]:",
+       "tags-edit-revision-legend": "Afegeix o suprimeix etiquetes {{PLURAL:$1|d'aquesta revisió|de totes les $1 revisions}}",
        "tags-edit-logentry-legend": "Afegeix o suprimeix etiquetes {{PLURAL:$1|d'aquesta entrada del registre|de totes les entrades del registre}}",
        "tags-edit-existing-tags": "Etiquetes existents:",
        "tags-edit-existing-tags-none": "<em>Cap</em>",
index dcc4c5c..ee26071 100644 (file)
        "page_last": "тlаьххьара",
        "histlegend": "Кхетор: (хӀинцалера.) — йолучу башхон къастам; (хьалх.) — хьалхалерчу башхон къастам; '''ж''' — жимо бозалца болу хийцам.",
        "history-fieldset-title": "АгӀона хийцамаш",
-       "history-show-deleted": "Ð\94Ó\80аÑ\8fÑ\85инарш",
+       "history-show-deleted": "Ð\94Ó\80аÑ\8fÑ\8cÑ\85нарш",
        "histfirst": "ширниш",
        "histlast": "хьалхарниш",
        "historysize": "($1 {{PLURAL:$1|байт}})",
index 7e9eecf..a2a081a 100644 (file)
        "rollbacklinkcount-morethan": "vrácení více než $1 {{PLURAL:$1|editace|editací}} zpět",
        "rollbackfailed": "Nešlo vrátit zpět",
        "rollback-missingparam": "V požadavku chybí povinné parametry.",
+       "rollback-missingrevision": "Nepodařilo se načíst data revize.",
        "cantrollback": "Nelze vrátit zpět poslední editaci, neboť poslední přispěvatel je jediným autorem této stránky.",
        "alreadyrolled": "Nelze vrátit zpět poslední editaci [[:$1]] od uživatele [[User:$2|$2]] ([[User talk:$2|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), protože někdo jiný již stránku editoval nebo vrátil tuto změnu zpět.\n\nPoslední editaci této stránky {{GENDER:$3|provedl|provedla|provedl uživatel}} [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Shrnutí editace bylo: <em>$1</em>.",
        "linkaccounts-submit": "Propojit účty",
        "unlinkaccounts": "Zrušení propojení účtů",
        "unlinkaccounts-success": "Propojení účtu bylo zrušeno.",
-       "authenticationdatachange-ignored": "Změna autentizačních údajů nebyla zpracována. Možná není nakonfigurován žádný poskytovatel?"
+       "authenticationdatachange-ignored": "Změna autentizačních údajů nebyla zpracována. Možná není nakonfigurován žádný poskytovatel?",
+       "userjsispublic": "Uvědomte si prosím, že podstránky s JavaScriptem by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům.",
+       "usercssispublic": "Uvědomte si prosím, že podstránky s CSS by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům."
 }
index 5e989ef..13b9137 100644 (file)
        "rollbacklinkcount-morethan": "Mehr als {{PLURAL:$1|eine Version|$1 Versionen}} zurücksetzen",
        "rollbackfailed": "Zurücksetzen gescheitert",
        "rollback-missingparam": "In der Anfrage fehlen erforderliche Parameter.",
+       "rollback-missingrevision": "Die Versionsdaten konnten nicht geladen werden.",
        "cantrollback": "Die Änderung kann nicht zurückgesetzt werden, da es keine früheren Autoren gibt.",
        "alreadyrolled": "Das Zurücksetzen der Änderungen von [[User:$2|$2]] ([[User talk:$2|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) an [[:$1]] ist gescheitert, da in der Zwischenzeit ein anderer Benutzer die Seite geändert hat.\n\nDie letzte Änderung stammt von [[User:$3|$3]] ([[User talk:$3|Diskussion]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Die Änderungszusammenfassung lautet: <em>$1</em>.",
        "revertmove": "zurück verschieben",
        "delete_and_move_text": "Die Seite „[[:$1]]“ existiert bereits.\nMöchtest du diese löschen, um die Seite verschieben zu können?",
        "delete_and_move_confirm": "Ja, Seite löschen",
-       "delete_and_move_reason": "gelöscht, um Platz für die Verschiebung von „[[$1]]“ zu machen",
+       "delete_and_move_reason": "Gelöscht, um Platz für die Verschiebung von „[[$1]]“ zu machen",
        "selfmove": "Ursprungs- und Zielname sind gleich.\nEine Seite kann nicht auf sich selbst verschoben werden.",
        "immobile-source-namespace": "Seiten des „$1“-Namensraums können nicht verschoben werden",
        "immobile-target-namespace": "Seiten können nicht in den „$1“-Namensraum verschoben werden",
index a99ff64..388d6c2 100644 (file)
        "about": "Heqa cı de",
        "article": "Pela zerreki",
        "newwindow": "(pençereyê newey de beno a)",
-       "cancel": "Bıtexelne",
+       "cancel": "İbtal kı",
        "moredotdotdot": "Vêşi...",
        "morenotlisted": "Vêşi lista nêbi...",
        "mypage": "Pele",
        "specialpage": "Pela xısusiye",
        "personaltools": "Hacetê şexsiy",
        "articlepage": "Pera zerreki bıvin",
-       "talk": "Werênayış",
+       "talk": "Hurênayış",
        "views": "Asayışi",
        "toolbox": "Haceti",
        "userpage": "Pela karberi bıvêne",
        "viewhelppage": "Pera peşti bıvin",
        "categorypage": "Pela kategoriya bıasne",
        "viewtalkpage": "Werênayışi bıvêne",
-       "otherlanguages": "Zıwananê binan de",
+       "otherlanguages": "Tayna zıwanan dı",
        "redirectedfrom": "($1 ra kırışı yê)",
        "redirectpagesub": "Pela berdışi",
        "redirectto": "Beno hetê:",
-       "lastmodifiedat": "Per roca $1, sehat $2 de biye neye.",
+       "lastmodifiedat": "Per roca $1, sehat $2 de biya anewe.",
        "viewcount": "Ena pele {{PLURAL:$1|rae|$1 rey}} vêniya.",
        "protectedpage": "Pela pawıtiye",
        "jumpto": "Şo be:",
        "nstab-main": "Pele",
        "nstab-user": "Pela karberi",
        "nstab-media": "Pela medya",
-       "nstab-special": "Pela xase",
+       "nstab-special": "Pera spesiyal",
        "nstab-project": "Pela proceyi",
        "nstab-image": "Dosya",
        "nstab-mediawiki": "Mesac",
        "publishpage": "Perer bıhesırne",
        "publishchanges": "Vurnayışa vıla ke",
        "preview": "Verqayt",
-       "showpreview": "Verqayti bımocne",
-       "showdiff": "Vurriyayışan bımocne",
+       "showpreview": "Verasayışi bıvin",
+       "showdiff": "Vuryayışa bıasne",
        "anoneditwarning": "<strong>İqaz:</strong> Şıma be hesabê xo nêkewtê cı. \nAdresê şımayê IP tarixê vırnayışê na pele de do qeyd bo. Eke şıma <strong>[$1 cıkewê]</strong> ya zi <strong>[$2 hesab vırazê]</strong>, vurnayışê şıma be zewbina kare ra nameyê şıma rê bar beno.",
        "anonpreviewwarning": "\"Şıma be hesabê xo nêkewtê cı. Eke qeyd kerê, adresê şımaê IP tarixê vırnayışê na pele de do qeyd bo.\"",
        "missingsummary": "'''DİQET:''' Şıma jû xulasa nênuşte.\nEke şıma \"{{int:savearticle}}\" reyna bıtıknê, vırnayışê şıma bê xulasa qeyd beno.",
        "page_first": "verên",
        "page_last": "peyên",
        "histlegend": "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />\nCedwel: <strong>({{int:ferq}})</strong> = ferqê verziyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
-       "history-fieldset-title": "Tarixi bıvêne",
+       "history-fieldset-title": "Çımberz verori",
        "history-show-deleted": "Tenya esterıtey",
        "histfirst": "Verênêr",
        "histlast": "Peyênêr",
        "recentchanges-summary": "Wiki sero vurriyayışê peyêni asenê.",
        "recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
        "recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
-       "recentchanges-label-newpage": "Enê vurnayışi ra yew pela newiye vıraziye",
+       "recentchanges-label-newpage": "Enê vurnayışi ra yu pera newi vıraziya ya",
        "recentchanges-label-minor": "Vurriyayışo werdiyo",
        "recentchanges-label-bot": "Eno vurnayış terefê yew boti ra vıraziyo",
        "recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
        "recentchanges-label-plusminus": "Ebadê pele de bazê bayti de vayeyê cı",
        "recentchanges-legend-heading": "<strong>Kıtabekê Vurriyayışê peyêni:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|Lista pelanê neweyan]] zi bıvêne)",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} Şıma şenê ([[Special:NewPages|Listey peranê  newan]] zi bıvinê)",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Bıasne",
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
        "rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
        "rcshowhideminor": "vurriyayışê werdi $1",
-       "rcshowhideminor-show": "Bımocne",
+       "rcshowhideminor-show": "Bıasne",
        "rcshowhideminor-hide": "Bınımne",
        "rcshowhidebots": "botan $1",
-       "rcshowhidebots-show": "Bımocne",
+       "rcshowhidebots-show": "Bıasne",
        "rcshowhidebots-hide": "Bınımne",
        "rcshowhideliu": "karberê qeydbiyayeyi $1",
        "rcshowhideliu-show": "Bıasne",
        "rcshowhideliu-hide": "Bınımne",
        "rcshowhideanons": "karberê bênameyi $1",
-       "rcshowhideanons-show": "Bımocne",
+       "rcshowhideanons-show": "Bıasne",
        "rcshowhideanons-hide": "Bınımne",
        "rcshowhidepatr": "$1 vurnayışê ke dewriya geyrayê",
        "rcshowhidepatr-show": "Bıasne",
        "rcshowhidepatr-hide": "Bınımne",
        "rcshowhidemine": "vurnayışanê mı $1",
-       "rcshowhidemine-show": "Bımocne",
+       "rcshowhidemine-show": "Bıasne",
        "rcshowhidemine-hide": "Bınımne",
        "rcshowhidecategorization": "kategorizasyonê pele $1",
        "rcshowhidecategorization-show": "Bıasne",
        "rcshowhidecategorization-hide": "Bınımne",
-       "rclinks": "Peyniya $2 rocan de $1 vurriyayışê <br />$3 asenê",
+       "rclinks": "Peyniya $2 rocan de $1 vurriyayışan ra <br />$3 asenê",
        "diff": "ferq",
        "hist": "verên",
        "hide": "Bınımne",
-       "show": "Bımocne",
+       "show": "Bıasne",
        "minoreditletter": "q",
        "newpageletter": "N",
        "boteditletter": "b",
        "namespace_association": "Heruna nameyanê elaqedaran",
        "tooltip-namespace_association": "Herunda canemiya elekeyın nışan kerdışi sero qıse kerdışi yana zerre dekerdışi rê ena dora tesdiqi nışan kerê",
        "blanknamespace": "(Ser)",
-       "contributions": "İştiraqê {{GENDER:$1|karber}}i",
+       "contributions": "İştirakê {{GENDER:$1|karber}}i",
        "contributions-title": "Dekerdenê karber de $1",
        "mycontris": "İştıraki",
        "anoncontribs": "İştıraki",
        "import-rootpage-nosubpage": "Qan de bınnaman reçe de \"$1\" re mısade nedano.",
        "importlogpage": "Qeydê ragozi",
        "importlogpagetext": "wiki yo ke nişane biyo tera kırıştışê zerredayişi nêbeno.",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|çımraviyarnayış|çımraviyarnayışi}}",
-       "import-logentry-interwiki-detail": "$2 ra $1 {{PLURAL:$1|çımraviyarnayış|çımraviyarnayışi}}",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|revizyon|revizyon}} debya zere",
+       "import-logentry-interwiki-detail": "$2 per da $1  ra{{PLURAL:$1|revizyon|revizyon}} debya zere",
        "javascripttest": "Cerebnayışê JavaScripti",
        "javascripttest-qunit-intro": "Mediawiki.org dı [dokumanê $1] bıvinê.",
        "tooltip-pt-userpage": "Pela {{GENDER:|şımaya karberi}}",
        "tooltip-t-recentchangeslinked": "Vurnayışê peyênê pelanê ke ena pela ra gırê biyê",
        "tooltip-feed-rss": "RSS feed qe ena pele",
        "tooltip-feed-atom": "Qe ena pele atom feed",
-       "tooltip-t-contributions": "Yew lista iştırakanê {{GENDER:$1|nê karberi}}",
-       "tooltip-t-emailuser": "Ena karber ri yew email bışırav",
+       "tooltip-t-contributions": "{{GENDER:$1|Enê karberi}} ra listey iştirakan",
+       "tooltip-t-emailuser": "Ena karber ri yew email bırış",
        "tooltip-t-upload": "Dosyeyan bar ke",
        "tooltip-t-specialpages": "Yew lista pelanê xasanê pêroyinan",
        "tooltip-t-print": "Hewl versiyona ploğnayışa na perer",
        "tooltip-ca-nstab-special": "Na pelaya xas a, şıma nêşenê sero vurnayış bıkerê",
        "tooltip-ca-nstab-project": "Pela proceyi bıvêne",
        "tooltip-ca-nstab-image": "Pera dosyayer bıvin",
-       "tooltip-ca-nstab-mediawiki": "Mesacê sistemi bıne",
+       "tooltip-ca-nstab-mediawiki": "Mesacê sistemi bıasne",
        "tooltip-ca-nstab-template": "Şabloni bıvêne",
        "tooltip-ca-nstab-help": "Pela peşti bıvêne",
        "tooltip-ca-nstab-category": "Pela kategoriye bıvêne",
        "lastmodifiedatby": "Ena per tewr peyên roca $2, $1 de terefê $3 ra vurmaya ya.",
        "othercontribs": "xebatê $1 ıney geriyayo diqqeti/geriyayo nezer.",
        "others": "bini",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|karberê ey|karberanê ey}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|karber|karberan}} $1",
        "anonusers": "{{SITENAME}} {{PLURAL:$2|karberê eyê|karberanê eyê}} anonimi $1",
        "creditspage": "şınasnameyê peli",
        "nocredits": "qey no peli hema/hona yew şınasnameyi mewcud niyo",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Kategoriya nımıtiye|Kategoriyê nımıtey}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Şablono|Şablonê}} ke mocniyenê ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|1 Pele|$1 Pelan}} de bestiya pıra",
-       "pageinfo-toolboxlink": "Melumatê pele",
+       "pageinfo-toolboxlink": "Zanayışa perer",
        "pageinfo-redirectsto": "Beno hetê",
        "pageinfo-redirectsto-info": "melumat",
        "pageinfo-contentpage": "Zey jû pela zerreki hesebiyena",
        "scarytranscludefailed-httpstatus": "[Qande $1 şablon nêşa bıgêriyo: HTTP $2]",
        "scarytranscludetoolong": "[Ena URL zaf dergo]",
        "deletedwhileediting": "'''Teme''': Ena pele  verniyê ti de eseteriyaya!",
-       "confirmrecreate": "Karberê [[User:$1|$1]]î ([[User talk:$1|mesac]]), verniyê vurnayîşê ti ra ena pele wedarno, sebeb: ''$2''\nMa rica keno tesdiq bike ke ti raştî wazeno eno pel bivirazo.",
-       "confirmrecreate-noreason": "karbero [[User:$1|$1]] ([[User talk:$1|mesac]]) , dest pêkerdışiena pela sero vurnayışiya tepya ena pela besternê. Şıma qayıli ke ena pela fına vırazê se ena pela tesdiq kerê.",
+       "confirmrecreate": "Karberê [[User:$1|$1]]i ([[User talk:$1|mesac]]), verniyê vurnayışê to ra ena pele {{GENDER:$1|wedarna}}, sebeb: ''$2''\nMa rica kem tesdiq kerê ke şıma qayılêena per fına bıvorazi yo.",
+       "confirmrecreate-noreason": "karbero [[User:$1|$1]] ([[User talk:$1|mesac]]) , dest pêkerdışiena pela sero vurnayışiya tepya ena pela {{GENDER:$1|besternê}}. Şıma qayıli ke ena pela fına vırazê se ena pela tesdiq kerê.",
        "recreate": "Werzayne",
        "unit-pixel": "px",
        "confirm_purge_button": "Temam",
        "logentry-newusers-create2": "Hesabê karberi $1 terefê $3 ra {{GENDER:$2|vıraziya}}",
        "logentry-newusers-byemail": "Karber $1 hesabe $3 {{GENDER:$2|virast}} u parola rist epostadaci",
        "logentry-newusers-autocreate": "Hesabê karberi $1 otomatikmen {{GENDER:$2|vıraşt}}",
-       "logentry-rights-rights": "$1 qandê $3 rê ezayiya grube $4 ra $5 {{GENDER:$2|vuriye}}",
+       "logentry-rights-rights": "$1 qandê {{GENDER:$6|$3}} rê ezayiya grube $4 ra $5 {{GENDER:$2|vuriye}}",
        "logentry-rights-rights-legacy": "$1 qandê $3 rê ezayiya grube {{GENDER:$2|vuriye}}",
        "logentry-rights-autopromote": "$1 otomatikmen $4 ra $5 {{GENDER:$2|terfi bi}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|bar kerd}} $3",
        "expand_templates_generate_xml": "Dara XML arêdayoği bımocne",
        "expand_templates_generate_rawhtml": "Xam HTML'i bıvin",
        "expand_templates_preview": "Verqayt",
-       "pagelanguage": "Weçinıtoğê zıwanê pele",
+       "pagelanguage": "Zıwanê perer bıvırnê",
        "pagelang-name": "Pele",
        "pagelang-language": "Zıwan",
        "pagelang-use-default": "Zıwanê hesabiyayeyi bıgurene",
        "pagelang-select-lang": "Zıwan weçine",
        "right-pagelang": "Zıwanê pele bıvurne",
        "action-pagelang": "zıwanê pele bıvurne",
-       "log-name-pagelang": "Qeydê zıwani bıvurne",
+       "log-name-pagelang": "Qeydê vurriyayışa zıwani",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 bayt|$1 bayti}} ($2; $3%)",
        "mediastatistics-table-mimetype": "Tewrê MIME",
        "special-characters-group-latin": "Latin",
index 61e06c0..67bedaa 100644 (file)
        "userrights-reason": "कारण:",
        "userrights-unchangeable-col": "तमीले परिवर्तन गद्द नसक्ने समूहहरू",
        "userrights-conflict": "प्रयोगकर्ताको अधिकार परिवर्तनमी मतभेद भयो ! कृपया तमरो परिवर्तन पुनरावलोकन तथा पुष्टि गर ।",
-       "userrights-removed-self": "तमà¥\80लà¥\87 à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤\86फà¥\8dनà¥\8b à¤\85धिà¤\95ारहरà¥\82लाà¤\88 à¤®à¥\87à¤\9fायà¥\8c à¥¤ à¤¤à¥\8dयà¥\88 à¤\95ारण à¤¤à¤®à¥\80 à¤\85ब यो पानो हेद्द नाइसक्दा ।",
+       "userrights-removed-self": "तमलà¥\87 à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤\86फनà¥\8b à¤\85धिà¤\95ारहरà¥\82लाà¤\88 à¤®à¥\87à¤\9fाया à¥¤ à¤¤à¥\8dयà¥\88 à¤\95ारण à¤¤à¤® à¤\86ब यो पानो हेद्द नाइसक्दा ।",
        "group": "समूह:",
        "group-user": "प्रयोगकर्ताहरू",
        "group-autoconfirmed": "स्वत स्थापित प्रयोगकर्ताहरू",
        "group-sysop-member": "{{GENDER:$1|प्रबन्धक}}",
        "group-bureaucrat-member": "{{GENDER:$1|प्रशासक}}",
        "group-suppress-member": "{{GENDER:$1|दबाउन्या}}",
-       "grouppage-user": "{{एनयस:आयोजना}}:प्रयोगकर्ताहरू",
+       "grouppage-user": "{{ns:project}}:प्रयोगकर्ताहरू",
        "grouppage-autoconfirmed": "{{एनयस:आयोजना}}:स्वनिर्धारित प्रयोगकर्ताहरू",
        "grouppage-bot": "{{एनयस:आयोजना}}:बोटहरु",
-       "grouppage-sysop": "{{एनयस:आयोजना}}:प्रबन्धकहरु",
+       "grouppage-sysop": "{{ns:project}}:प्रबन्धकहरू",
        "grouppage-bureaucrat": "{{एनयस:आयोजना}}:प्रशासकहरू",
        "grouppage-suppress": "{{एनयस:आयोजना}}:लुकौन्या",
        "right-read": "पृष्ठहरू पढ",
        "right-upload_by_url": "URL बठे फाइल उर्ध्वभरण गर्ने",
        "right-purge": "साइटको क्याश( cache) निश्चित नगरिकनै पर्ज(Purge) गर्ने",
        "right-writeapi": "लेखन API प्रयोग गद्य्या",
+       "right-delete": "पृष्ठहरू मेट्ने",
        "right-bigdelete": "लामो इतिहास भयाका पानाहरू मेट्ट्या",
        "right-deleterevision": "खुलाइयाको पानाहरू मेटाउन्या र मेटायाको रद्द गद्या",
        "right-deletedtext": "मेट्याका संशोधन बीचका मेट्याका पाठ र परिवर्तनहरू हेद्या",
+       "right-undelete": "मेट्याको पाना फर्काउने",
        "right-suppressionlog": "व्यक्तिगत लगहरू हेद्या",
        "right-block": "अरु प्रयोगकर्तानलाई सम्पादन गद्दाकी ब्लक गर",
        "right-unblockself": "आफुलाई खुल्ला गर ।",
index 0c6b8ef..7a99fe3 100644 (file)
        "morenotlisted": "Cl'elèinch ché an n'é mìa finî.",
        "mypage": "Pàgina",
        "mytalk": "Al mē discusiòun",
-       "anontalk": "Discusiòun per cl' IP ché",
+       "anontalk": "Discusiòun",
        "navigation": "Navigasiòun",
        "and": "&#32;e",
        "qbfind": "Câta",
        "laggedslavemode": "'''Atèinti:''' la pàgina la pré avèir mìa al revisiòun pió nōv.",
        "readonly": "'Database' bluchê",
        "enterlockreason": "Scréver al mutîv dal blôch, precişêr quând a 's pèinsa che 'l vègna tôt via.",
-       "readonlytext": "In cól mumèint ché al databêş l'é bluchê e an 's pōlen fêr né zûnti né mudéfichi. Al blôch ed sôlit l'é lighê a 'na revişiòun normêla e quând la srà finîda al gnirà sbluchê. \n\nL'aminitradōr dal sistēma ch' al l'à bluchê l'à dê cla spiegasiòun ché: $1",
+       "readonlytext": "In cól mumèint ché al databêş l'é bluchê e an 's pōlen fêr né zûnti né mudéfichi. Al blôch ed sôlit l'é lighê a 'na revişiòun normêla e quând la srà finîda al gnirà sbluchê. \n\nL'aminitradōr dal sistēma ch' l'à urdnê 'l blôch l'à dê cla spiegasiòun ché: $1",
        "missing-article": "Al datebêş an n'à mìa catê al tèst ed 'na pàgina ch' l' aré duvû catêres sòt' al nòm \"$1\" $2. Ed sôlit còst a sucēd quând a vîn arciamê, a partîr da la stòria dal mudéfichi o dal cunfrûnt tra versiòun, un colegamèint a 'na pàgina scanşlêda, a un cunfrûnt tra versiòun che gh'în mìa o a un cunfrûnt tra versiòun cun la stòria dal mudéfichi scanşlêda. In chês cuntrâri, a s'é pubabilmèint catê un erōr int al prugrâma ed Media Wiki. A se dmânda al piaşèir ed comunichêr còl ch'é sucès a un [[Special:ListUsers/sysop|amministadōr]] e comunichêregh l'indirés (URL) in quistiòun.",
        "missingarticle-rev": "(nómer ed la versiòun: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "viewsource": "Guêrda la surzéia",
        "viewsource-title": "Guêrda la surzéia 'd $1",
        "actionthrottled": "L'asiòun la vîn tardêda.",
-       "actionthrottledtext": "Cme mişûra 'd sicurèsa cûnt'r al spam soquânti operasiòun a vînen limitêdi a 'n nómer mâsim ed vôlti in un precîş peréiod ed tèimp, in cól chêş ché a s'é bèle andê d'ed là 'd cól lémit. A se dmânda ed turnêr a pruvêr tra soquânt minût.",
+       "actionthrottledtext": "Cme mişûra 'd sicurèsa cûntra l'abûş soquânti operasiòun a vînen limitêdi a 'n nómer mâsim ed vôlti in un precîş peréiod ed tèimp, in cól chêş ché a 's é bèle andê d'ed là 'd cól lémit. A 's e-dmânda 'd turnêr a pruvêr tra soquânt minût.",
        "protectedpagetext": "Cla pàgina ché l'é stêda prutèta per impidîr la mudéfica o êtri operasiòun.",
        "viewsourcetext": "L'é pusébil vèder e cupiêr al côdis surzéia ed cla pàgina ché.",
        "viewyourtext": "L'é pusébil vèder e cupiêr al côdis surzéia dal <strong>tō mudéfichi</strong> ed cla pàgina ché.",
        "protectedinterface": "Cla pàgina ché la gh'à 'n elemèint ch' al fa pêrt dal colegamèint tra utèint e al progrâma 'd cól sît ché e l'é prutèta per schivşêr pusébil abûş. Per zuntêr o mudufichêr tradusiòun per tót i sistēma wiki druvêr [https://translatewiki.net/ translatewiki.net], al prugèt 'd adatamèint a ògni léngva 'd MediaWiki.",
        "editinginterface": "<strong>Atèinti:</strong> Al tèst ed cla pàgina ché 'l fa pêrt dal colegamèint tra utèint e 'l prugrâma dal sît.  Tót' al modéfichi fâti a cla pàgina ché a se spècen in sém a i mesâg vést per tót j utèint ed cól wiki ché.",
        "translateinterface": "Per zuntêr o mudifichêr al tradusiòun vâlidi in sém a tót i wiki, drōva [https://translatewiki.net/ translatewiki.net], al prugèt Media Wiki p'r al léngui di divêrs pôst.",
-       "cascadeprotected": "Insém a cla pàgina ché an n'é mìa pusébil fêr dal mudéfichi perchè l'é dèinter {{PLURAL:$1|int la pàgina sgnêda ché  'd sègvit, ch' l'é stêda prutèta|int al pàgini sgnêdi ché  'd sègvit, ch' în stêdi prutèti}} cun la prutesiòun ch' la 's arfà in cuntinvasiòun:\n$2",
+       "cascadeprotected": "In sém a cla pàgina ché an n'é mìa pusébil fêr dal mudéfichi perchè l'é dèinter {{PLURAL:$1|int la pàgina sgnêda ché  'd sègvit, ch' l'é stêda prutèta|int al pàgini sgnêdi ché  'd sègvit, ch' în stêdi prutèti}} cun la prutesiòun ch' la 's arfà in cuntinvasiòun:\n$2",
        "namespaceprotected": "An 's gh'à mìa i permès necesâri per mudifichêr al pàgini dal spâsi di nòm <strong>$1</strong>.",
        "customcssprotected": "An 's gh'à mìa i permès necesâri per mudifichêr cla pàgina CSS ché, perchè la gh'à dèinter al j impustasiòun personêli 'd n' êter utèint.",
        "customjsprotected": "An 's gh'à mìa i permès necesâri per mudifichêr cla pàgina JavaScript ché, perchè la gh'à dèinter al j impustasiòun personêli 'd n' êter utèint.",
        "mypreferencesprotected": "An 's gh'à mìa i permès necesâri per cambiêr al preferèinsi personêli.",
        "ns-specialprotected": "An n'é mìa pusébil mudifichêr al pàgini specêli.",
        "titleprotected": "Al tétol ed cla pagina ché l'é stê bluchê da [[User:$1|$1]].\nCòst l'é al mutîv: <em>$2</em>.",
-       "filereadonlyerror": "An n'é mìa stê pusébil mudifichêr al file \"$1\" perchè al depôsit di file \"$2\" a 's pōl sōl lēzer.\n\nL'aministradōr ch' al l'à bluchê l'à dê cla spiegasiòun ché:\"$3\".",
+       "filereadonlyerror": "An n'é mìa stê pusébil mudifichêr al file \"$1\" perchè al depôsit di file \"$2\" a 's pōl sōl lēzer.\n\nL'aministradōr dal sistēma ch' al l'à bluchê l'à dê cla spiegasiòun ché:\"$3\".",
        "invalidtitle-knownnamespace": "Tétol mìa vâlid cme spâsi di nòm \"$2\" e tèst \"$3\"",
        "invalidtitle-unknownnamespace": "Tétol mìa vâlid cun spâsi di nòm mìa cgnusû \"$1\" e tèst \"$2\"",
        "exception-nologin": "An t'é mìa gnû dèinter",
        "createacct-reason": "Mutîv",
        "createacct-reason-ph": "Perchè ét drē fêr 'n' êtra utèinsa",
        "createacct-submit": "Fà la tó utèinsa",
-       "createacct-another-submit": "Fà 'n' êtra utèinsa.",
+       "createacct-another-submit": "Fà l' utèinsa.",
        "createacct-benefit-heading": "{{SITENAME}} crès grâsia a persòuni cme té.",
        "createacct-benefit-body1": "{{PLURAL:$1|mudéfica|mudéfichi}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pàgina|pàgini}}",
        "nocookieslogin": "Per fêr l'ingrès a {{SITENAME}} a 's dēv druvêr i cookie che rişûlten bluchê. Tōrna fêr l'ingrès dôp avèir şbluchê i cookie int al tó navigadōr.",
        "nocookiesfornew": "L'iscrisiòun utèint an n'é mìa stêda fâta, perchè òm mìa prû cunfermêr la só urégin. Veréfica 'd avèir şbluchê i cookie, tōrna carghêr cla pàgina ché e prōva incòra.",
        "noname": "Al nòm utèint scrét an n'é mìa vâlid.",
-       "loginsuccesstitle": "Ingrès fât.",
+       "loginsuccesstitle": "Fât l'ingrès.",
        "loginsuccess": "''' T'é stê coleghê al terminêl {{SITENAME}} cun al nòm utèint '''$1'''.",
-       "nosuchuser": "An n'é mìa registrê nisûn utèint cun al nòm \"$1\". I nòm utèin în sensébil al lètri grândi. Veréfica al nòm scrét o [[Special:CreateAccount|fà un nōv ingrès]].",
+       "nosuchuser": "An n'é mìa registrê nisûn utèint cun al nòm \"$1\". I nòm utèin în sensébil al lètri grândi. Veréfica al nòm scrét o [[Special:CreateAccount|fà 'na nōva utèinsa]].",
        "nosuchusershort": "An gh'é mìa registrê un utèint ciamê ''$1''. Veréfica al nòm scrét.",
        "nouserspecified": "L'é necesâri precişêr un nòm utèint.",
        "login-userblocked": "Cl'utèinsa ché l'é bluchêda. An n'é pusébil fêr l'ingrès.",
        "passwordreset-emailtext-user": "L'utèint $1 ed {{SITENAME}} l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:\n\n$2 \n\n{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria ché la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. \n\nSe t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia",
        "passwordreset-emailelement": "Nòm utèint: \n$1\n.\nCêva 'd ingrès pruvişôria: \n$2",
        "passwordreset-emailsentemail": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès.",
-       "passwordreset-emailsent-capture": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, ché sòta a gh'é al tèst che gh'é scrét.",
-       "passwordreset-emailerror-capture": "É stê fât un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, scréta ché 'd sègvit. La spedisiòun {{GENDER:$2|a l'utèint}} an n'é mia 'riusîda:$1",
        "changeemail": "Câmbia l'indirés ed la pôsta eletrônica",
        "changeemail-header": "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
        "changeemail-no-info": "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
        "undo-nochange": "A sèmbra che la mudéfica la sìa bèle stêda scanşlêda.",
        "undo-summary": "Scanşlê la mudéfica $1 ed [[Special:Contributions/$2|$2]]\n([[User talk:$2|discusiòun]])",
        "undo-summary-username-hidden": "Scanşlê la modéfica $1 ed 'n utèin lughê",
-       "cantcreateaccounttitle": "Impusébil registrêr un utèint",
        "cantcreateaccount-text": "La registrasiòun ed cl'indirés IP ché ('''$1''') l'é stêda bluchêda da [[User:$3|$3]]. \n\nAl mutîv dal blôch dê da $3 l'é còst: ''$2''.",
        "cantcreateaccount-range-text": "La registrasiòun da indirés IP int l'intervâl <strong>$1</strong>, in dó gh'é dèinter al tó  (<strong>$4</strong>), l'é stêda bluchêda da [[User:$3|$3]]. \n\nAl mutîv dê da $3 l'é <em>$2</em>",
        "viewpagelogs": "Guêrda la stòria 'd cla pàgina ché",
index 892ac2c..dcd3981 100644 (file)
        "rollbacklinkcount-morethan": "rollback more than $1 {{PLURAL:$1|edit|edits}}",
        "rollbackfailed": "Rollback failed",
        "rollback-missingparam": "Missing required parameters on request.",
+       "rollback-missingrevision": "Unable to load revision data.",
        "cantrollback": "Cannot revert edit;\nlast contributor is only author of this page.",
        "alreadyrolled": "Cannot rollback last edit of [[:$1]] by [[User:$2|$2]] ([[User talk:$2|talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nsomeone else has edited or rolled back the page already.\n\nThe last edit to the page was by [[User:$3|$3]] ([[User talk:$3|talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "The edit summary was: <em>$1</em>.",
index 13eb863..6e92c24 100644 (file)
@@ -47,7 +47,8 @@
                        "Robin van der Vliet",
                        "Zciric",
                        "Psychoslave",
-                       "Orikrin1998"
+                       "Orikrin1998",
+                       "Gamliel Fishkin"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
@@ -90,7 +91,7 @@
        "tog-ccmeonemails": "Sendi al mi kopiojn de retpoŝtaĵoj, kiujn mi sendis al aliaj uzantoj.",
        "tog-diffonly": "Ne montri paĝan enhavon sub la ŝanĝmontrilo",
        "tog-showhiddencats": "Montri kaŝitajn kategoriojn",
-       "tog-norollbackdiff": "Nemontri diferencon post plenumado de ŝanĝomalfaro",
+       "tog-norollbackdiff": "Ne montri diferencon post plenumado de ŝanĝomalfaro",
        "tog-useeditwarning": "Averti min kiam mi forlasas redaktan paĝon kun nekonservitaj ŝanĝoj",
        "tog-prefershttps": "Ĉiam uzu sekuran konekton ensalutite",
        "underline-always": "Ĉiam",
        "period-am": "atm.",
        "period-pm": "ptm.",
        "pagecategories": "{{PLURAL:$1|Kategorio|Kategorioj}}",
-       "category_header": "Artikoloj en kategorio “$1”",
+       "category_header": "Paĝoj en kategorio “$1”",
        "subcategories": "Subkategorioj",
        "category-media-header": "Dosieroj en kategorio “$1”",
-       "category-empty": "<em>Tiu ĉi kategorio nuntempe enhavas neniun artikolon aŭ plurmedian dosieron.</em>",
+       "category-empty": "<em>Tiu ĉi kategorio nuntempe enhavas neniun paĝon aŭ plurmedian dosieron.</em>",
        "hidden-categories": "{{PLURAL:$1|Kaŝita kategorio|Kaŝitaj kategorioj}}",
        "hidden-category-category": "Kaŝitaj kategorioj",
        "category-subcat-count": "{{PLURAL:$2|Ĉi tiu kategorio havas nur la jenan subkategorion.|Ĉi tiu kategorio havas la {{PLURAL:$1|jenan subkategorion|$1 jenajn subkategoriojn}}, el $2 entute.}}",
        "noindex-category": "Neindeksitaj paĝoj",
        "broken-file-category": "Paĝoj kun rompita ligilo al dosiero",
        "about": "Pri",
-       "article": "Artikolo",
+       "article": "Enhava paĝo",
        "newwindow": "(en nova fenestro)",
        "cancel": "Nuligi",
        "moredotdotdot": "Pli...",
        "tagline": "El {{SITENAME}}",
        "help": "Helpo",
        "search": "Serĉi",
+       "search-ignored-headings": " #<!-- lasu ĉi tiun linion ekzakte kiel ĝi estas --> <pre>\n# Titoloj kiuj estos ignoritaj en serĉado.\n# Ŝanĝoj al ĉi tio efikas tuj kiam la paĝo kun la titolo estas indeksita.\n# Vi povas igi reindeksadon de paĝo, farinte nulan redakton.\n# La sintakso estas jena:\n#   * Io ajn ekde signo \"#\" ĝis la fino de la linio estas komento.\n#   * Ĉiu nemalplena linio estas la ekzakta titolo por ignori usklecon kaj kion ajn.\nReferencoj\nEksteraj ligiloj\nVidu Ankaŭ\n #</pre> <!-- lasu ĉi tiun linion ekzakte kiel ĝi estas -->",
        "searchbutton": "Serĉi",
        "go": "Ek",
        "searcharticle": "Ek",
-       "history": "Historio de versioj",
+       "history": "Historio de paĝo",
        "history_short": "Historio",
        "updatedmarker": "ĝisdatigita de post mia lasta vizito",
        "printableversion": "Presebla versio",
        "protect": "Protekti",
        "protect_change": "ŝanĝi",
        "protectthispage": "Protekti la paĝon",
-       "unprotect": "Ŝanĝi protekadon",
-       "unprotectthispage": "Ŝanĝi protektadon de ĉi tiu paĝo",
+       "unprotect": "Ŝanĝi protekton",
+       "unprotectthispage": "Ŝanĝi protekton de ĉi tiu paĝo",
        "newpage": "Nova paĝo",
        "talkpage": "Diskuti la paĝon",
        "talkpagelinktext": "diskuto",
        "specialpage": "Speciala paĝo",
        "personaltools": "Personaj iloj",
-       "articlepage": "Vidi paĝenhavon",
+       "articlepage": "Vidi enhavan paĝon",
        "talk": "Diskuto",
        "views": "Vidoj",
        "toolbox": "Iloj",
-       "userpage": "Vidi uzulan paĝon",
+       "userpage": "Vidi uzantopaĝon",
        "projectpage": "Rigardi projektopaĝon",
        "imagepage": "Vidi dosieropaĝon",
        "mediawikipage": "Vidi mesaĝopaĝon",
        "jumpto": "Iri al:",
        "jumptonavigation": "navigado",
        "jumptosearch": "serĉi",
-       "view-pool-error": "Bedaŭrinde la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun paĝon.\nBonvolu atendi iom antaŭ ol provi atingi ĝin denove.\n\n$1",
-       "generic-pool-error": "Bedaŭrinde la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun risurcon.\nBonvolu iom atendi antaŭ vi provos atingi ĝin denove.",
+       "view-pool-error": "Pardonon, la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun paĝon.\nBonvolu atendi iom antaŭ ol provi atingi ĝin denove.\n\n$1",
+       "generic-pool-error": "Pardonon, la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun risurcon.\nBonvolu iom atendi antaŭ vi provos atingi ĝin denove.",
        "pool-timeout": "Tempolimo atingita dum atendo de ŝlosado",
        "pool-queuefull": "Atendovico de servilaro estas plena.",
        "pool-errorunknown": "Nekonata eraro",
        "ok": "Bone",
        "retrievedfrom": "Elŝutita el  \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|Vi havas}} $1 ($2).",
-       "youhavenewmessagesfromusers": "Riceviĝis $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
+       "youhavenewmessagesfromusers": "Riceviĝis $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).\n\nVi havas $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
        "youhavenewmessagesmanyusers": "Riceviĝis $1 de multaj uzantoj ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|nova mesaĝo|999=novaj mesaĝoj}}",
        "newmessagesdifflinkplural": "$1 {{PLURAL:$1|ŝanĝo|ŝanĝoj}}",
        "rollbacklinkcount-morethan": "nuligi pli ol $1 {{PLURAL:$1|redakton|redaktojn}}",
        "rollbackfailed": "Malfaro malsukcesis",
        "rollback-missingparam": "Mankas neprajn parametrojn de peto.",
+       "rollback-missingrevision": "Ne eblas ŝarĝi datumojn pri revizioj.",
        "cantrollback": "Ne povas restarigi antaŭan redakton; la redaktinto lasta estas la sola aŭtoro de la paĝo.",
        "alreadyrolled": "Ne povas restarigi la lastan redakton de [[:$1]] de la [[User:$2|$2]] ([[User talk:$2|diskuto]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\npro tio, ke oni intertempe redaktis aŭ restarigis la paĝon.\nLa lasta redaktinto estis [[User:$3|$3]] ([[User talk:$3|diskuto]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "La resumo de la redakto estis: <em>$1</em>.",
index 7099422..38de0a1 100644 (file)
        "rollbacklinkcount-morethan": "revertir más de $1 {{PLURAL:$1|edición|ediciones}}",
        "rollbackfailed": "No se pudo revertir",
        "rollback-missingparam": "Faltan parámetros requeridos en la solicitud.",
+       "rollback-missingrevision": "No se pueden cargar datos de la revisión.",
        "cantrollback": "No se puede revertir la edición;\nel último colaborador es el único autor de esta página.",
        "alreadyrolled": "No se puede revertir la última edición de [[:$1]] hecha por [[User:$2|$2]] ([[User talk:$2|discusión]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nalguien más ya ha editado o revertido esa página.\n\nLa última edición fue hecha por [[User:$3|$3]] ([[User talk:$3|discusión]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "El resumen de la edición fue: <em>$1</em>.",
        "sp-contributions-newbies-sub": "Para cuentas nuevas",
        "sp-contributions-newbies-title": "Contribuciones de usuarios nuevos",
        "sp-contributions-blocklog": "registro de bloqueos",
-       "sp-contributions-suppresslog": "contribuciones de {{GENDER:$1|usuario|usuaria}} suprimidas",
-       "sp-contributions-deleted": "contribuciones de {{GENDER:$1|usuario|usuaria}} borradas",
+       "sp-contributions-suppresslog": "contribuciones {{GENDER:$1|del usuario|de la usuaria}} suprimidas",
+       "sp-contributions-deleted": "contribuciones {{GENDER:$1|del usuario|de la usuaria}} borradas",
        "sp-contributions-uploads": "subidas",
        "sp-contributions-logs": "registros",
        "sp-contributions-talk": "discusión",
        "unlinkaccounts": "Desvincular cuentas",
        "unlinkaccounts-success": "Se ha desvinculado la cuenta.",
        "authenticationdatachange-ignored": "El cambio den los datos de autentificacion no fue realizado. ¿Tal vez, no se configuró un proveedor?",
-       "userjsispublic": "Recuerda: Las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
-       "usercssispublic": "Recuerda: Las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
+       "userjsispublic": "Recuerda: las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
+       "usercssispublic": "Recuerda: las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
 }
index a79df94..240be82 100644 (file)
        "mypreferencesprotected": "Ez daukazu eskumenik zure hobespenak aldatzeko.",
        "ns-specialprotected": "Ezin dira {{ns:special}} izen-tarteko orrialdeak editatu.",
        "titleprotected": "[[User:$1|$1]]ek izenburu hau sortzea ekidin zuen.\nEmandako arrazoia <em>$2</em> izan zen.",
-       "filereadonlyerror": "Ezin izan da \"$1\" fitxategia aldatu, \"$2\" fitxategi bilduma irakrutzeko-bakarrik moduan dagoelako.\n\nBlokeoa ezarri zuen administratzaileak honako arrazoia eman zuen: \"$3\".",
+       "filereadonlyerror": "Ezin izan da \"$1\" fitxategia aldatu, \"$2\" fitxategi bilduma irakrutzeko-bakarrik moduan dagoelako.\n\nBlokeoa ezarri zuen sistema administratzaileak honako arrazoia eman zuen: \"$3\".",
        "invalidtitle-knownnamespace": "Izenburua gaizki dago \"$2\" izen eremuan eta \"$3\" testuan",
        "invalidtitle-unknownnamespace": "Izenburua gaizki dago \"$1\" izen eremuan ezezagunean eta \"$2\" testuan",
        "exception-nologin": "Saioa hasi gabe",
index cfc4e4d..e265a0e 100644 (file)
        "watchthis": "پی‌گیری این صفحه",
        "savearticle": "صفحه ذخیره شود",
        "savechanges": "ذخیرهٔ تغییرات",
-       "publishpage": "ذخÛ\8cرÙ\87 صفحه",
-       "publishchanges": "ذخÛ\8cرÙ\87 تغییرات",
+       "publishpage": "اÙ\86تشار صفحه",
+       "publishchanges": "اÙ\86تشار تغییرات",
        "preview": "پیش‌نمایش",
        "showpreview": "پیش‌نمایش",
        "showdiff": "نمایش تغییرات",
        "right-block": "قطع دسترسی ویرایشی دیگر کاربران",
        "right-blockemail": "قطع دسترسی دیگر کاربران برای ارسال ایمیل",
        "right-hideuser": "قطع دسترسی کاربر و پنهان کردن آن از دید عموم",
-       "right-ipblock-exempt": "تاثیر نپذیرفتن از قطع دسترسی‌های آی‌پی، خودکار یا فاصله‌ای",
+       "right-ipblock-exempt": "تأثیر نپذیرفتن از قطع دسترسی‌های آی‌پی، خودکار یا فاصله‌ای",
        "right-unblockself": "بازکردن دسترسی خود",
        "right-protect": "تغییر میزان محافظت صفحات و ویرایش صفحات محافظت‌شده آبشاری",
        "right-editprotected": "ویرایش صفحه‌های محافظت‌شده به عنوان «{{int:protect-level-sysop}}»",
        "grant-group-high-volume": "انجام فعالیت‌های حجم بالا",
        "grant-group-customization": "سفارشی‌سازی و تنظیمات",
        "grant-group-administration": "انجام اقدامات مدیریتی",
+       "grant-group-private-information": "دسترسی به اطلاعات محرمانهٔ خودتان",
        "grant-group-other": "فعالیت‌های متفرقه",
        "grant-blockusers": "بستن و باز کردن کاربرها",
        "grant-createaccount": "ایجاد حساب‌های کاربری",
        "grant-highvolume": "ویرایش با حجم بالا",
        "grant-oversight": "پنهان کردن ویرایش‌ها",
        "grant-patrol": "تغییرات گشت صفحات",
+       "grant-privateinfo": "دسترسی به اطلاعات محرمانه",
        "grant-protect": "حفاظت و عدم حفاظت صفحات",
        "grant-rollback": "واگردانی  تغییرات صفحات",
        "grant-sendemail": "ارسال ایمیل به دیگر کاربران",
        "action-applychangetags": "اعمال برچسب بر روی تغییرات شما",
        "action-changetags": "افزودن یا حذف برچسب قراردادی بر روی نسخه یا سیاهه ورودی‌ها",
        "action-deletechangetags": "حذف برچسب‌ها از پایگاه داده",
+       "action-purge": "خالی‌کردن میانگیر این صفحه",
        "nchanges": "$1 تغییر",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|از آخرین بازدید}}",
        "enhancedrc-history": "تاریخچه",
        "uploadstash-errclear": "پاک‌کردن پرونده‌ها ناموفق بود.",
        "uploadstash-refresh": "تازه کردن فهرست پرونده‌ها",
        "uploadstash-thumbnail": "نمایش بندانگشتی",
+       "uploadstash-exception": "ناتوان از ذخیره کردن بارگذاری در نهانگاه ($1): ''$2''.",
        "invalid-chunk-offset": "جابجایی نامعتبر قطعه",
        "img-auth-accessdenied": "منع دسترسی",
        "img-auth-nopathinfo": "PATH_INFO موجود نیست.\nسرور شما برای ردکردن این مقدار تنظیم نشده‌است.\nممکن است مبتنی بر سی‌جی‌آی باشد و از img_auth پشتیبانی نکند.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization را ببینید.",
        "watchnologin": "به سامانه وارد نشده‌اید",
        "addwatch": "افزودن به فهرست پی‌گیری",
        "addedwatchtext": "«[[:$1]]» و صفحهٔ بحث آن به [[Special:Watchlist|فهرست پی‌گیری‌های]] شما اضافه شد.",
+       "addedwatchtext-talk": "''[[:$1]]'' و صفحهٔ مرتبط به آن به [[Special:Watchlist|فهرست پی‌گیری]] شما افزوده شدند.",
        "addedwatchtext-short": "صفحه \" $1 \" به فهرست پیگیریهای خود اضافه شده است.",
        "removewatch": "حذف از فهرست پی‌گیری",
        "removedwatchtext": "صفحهٔ «[[:$1]]» و صفحهٔ بحث آن از [[Special:Watchlist|فهرست پی‌گیری‌های شما]] برداشته شد.",
+       "removedwatchtext-talk": "''[[:$1]]'' و صفحهٔ مرتبط به آن از [[Special:Watchlist|فهرست پی‌گیری]] شما حذف شدند.",
        "removedwatchtext-short": "صفحهٔ \"$1\" از فهرست پیگیری‌های شما حذف شده‌است.",
        "watch": "پی‌گیری",
        "watchthispage": "پی‌گیری این صفحه",
        "rollbacklinkcount-morethan": "واگردانی بیش از $1 ویرایش",
        "rollbackfailed": "واگردانی نشد",
        "rollback-missingparam": "فقدان پارامترهای ضروری در درخواست",
+       "rollback-missingrevision": "ناتوان از بارگیری اطلاعات نسخه.",
        "cantrollback": "نمی‌توان ویرایش را واگرداند؛\nآخرین مشارکت‌کننده تنها مؤلف این مقاله است.",
        "alreadyrolled": "واگردانی آخرین ویرایش [[:$1]] توسط [[User:$2|$2]] ([[User talk:$2|بحث]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ممکن نیست؛\nپیش از این شخص دیگری مقاله را ویرایش یا واگردانی کرده‌است.\n\nآخرین ویرایش توسط [[User:$3|$3]] ([[User talk:$3|بحث]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) انجام شده‌است.",
        "editcomment": "خلاصهٔ ویرایش این بود:  <em>«$1»</em>.",
        "undeletehistorynoadmin": "این مقاله حذف شده‌است.\nدلیل حذف این مقاله به همراه مشخصات کاربرانی که قبل از حذف این صفحه را ویرایش کرده‌اند، در خلاصهٔ زیر آمده‌است.\nمتن واقعی این ویرایش‌های حذف شده فقط در دسترس مدیران است.",
        "undelete-revision": "نسخهٔ حذف شدهٔ $1 (به تاریخ $4 ساعت $5) توسط $3:",
        "undeleterevision-missing": "نسخه نامعتبر یا مفقود است.\nممکن است پیوندتان نادرست باشد یا اینکه نسخه از بایگانی حذف یا بازیابی شده باشد .",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|یک نسخه|$1 نسخه}} احیا نشد، چون <code>rev_id</code> آن {{PLURAL:$1|نسخه|نسخه‌ها}} از پیش مورد استفاده بود.",
        "undelete-nodiff": "نسخهٔ قدیمی‌تری یافت نشد.",
        "undeletebtn": "احیا",
        "undeletelink": "نمایش/احیا",
        "undeletedrevisions": "$1 نسخه احیا {{PLURAL:$1|شد}}",
        "undeletedrevisions-files": "$1 نسخه و $2 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
        "undeletedfiles": "$1 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
-       "cannotundelete": "احیا ناموفق بود:\n$1",
+       "cannotundelete": "تÙ\85اÙ\85 Û\8cا Ø¨Ø®Ø´Û\8c Ø§Ø² Ø§Ø­Û\8cا Ù\86اÙ\85Ù\88Ù\81Ù\82 Ø¨Ù\88د:\n$1",
        "undeletedpage": "'''$1 احیا شد'''\n\nبرای دیدن سیاههٔ حذف‌ها و احیاهای اخیر به  [[Special:Log/delete|سیاههٔ حذف]] رجوع کنید.",
        "undelete-header": "برای دیدن صفحه‌های حذف‌شدهٔ اخیر [[Special:Log/delete|سیاههٔ حذف]] را ببینید.",
        "undelete-search-title": "جستجوی صفحه‌های حذف‌شده",
        "sp-contributions-newbies-sub": "برای تازه‌کاران",
        "sp-contributions-newbies-title": "مشارکت‌های کاربری برای حساب‌های تازه‌کار",
        "sp-contributions-blocklog": "سیاههٔ بسته‌شدن‌ها",
-       "sp-contributions-suppresslog": "مشارکت‌های فرونشانی‌شده",
-       "sp-contributions-deleted": "مشارکت‌های حذف‌شدهٔ کاربر",
+       "sp-contributions-suppresslog": "مشارکت‌های فرونشانی‌شده {{GENDER:$1|کاربر}}",
+       "sp-contributions-deleted": "مشارکت‌های حذف‌شدهٔ {{GENDER:$1|کاربر}}",
        "sp-contributions-uploads": "بارگذاری‌ها",
        "sp-contributions-logs": "سیاهه‌ها",
        "sp-contributions-talk": "بحث",
        "linkaccounts-submit": "پیوند حساب کاربری",
        "unlinkaccounts": "حذف پیوند حساب کاربری",
        "unlinkaccounts-success": "پیوند کاربری بدون پیوند شد.",
-       "authenticationdatachange-ignored": "به تغيير اطلاعات احراز هويت پرداخته نشد. آیا ممکن است که هيچ مهيا کننده‌ای برای اين کار تنظيم نشده باشد؟"
+       "authenticationdatachange-ignored": "به تغيير اطلاعات احراز هويت پرداخته نشد. آیا ممکن است که هيچ مهيا کننده‌ای برای اين کار تنظيم نشده باشد؟",
+       "userjsispublic": "لطفاً توجه کنید: زیرصفحه‌های جاوااسکریپت نباید حاوی اطلاعات محرمانه باشند چون توسط دیگران قابل مشاهده هستند.",
+       "usercssispublic": "لطفاً توجه کنید: زیرصفحه‌های سی‌اس‌اس نباید حاوی اطلاعات محرمانه باشند چون توسط دیگران قابل مشاهده هستند."
 }
index c851a85..6c2190a 100644 (file)
        "mostlinkedcategories": "Catégories les plus utilisées",
        "mostlinkedtemplates": "Pages les plus incluses",
        "mostcategories": "Pages utilisant le plus de catégories",
-       "mostimages": "Fichiers les plus utilisés",
+       "mostimages": "Fichiers les plus liés",
        "mostinterwikis": "Pages avec le plus d'interwikis",
        "mostrevisions": "Pages les plus modifiées",
        "prefixindex": "Toutes les pages commençant par…",
        "rollbacklinkcount-morethan": "révoquer plus de $1 {{PLURAL:$1|modification|modifications}}",
        "rollbackfailed": "La révocation a échoué",
        "rollback-missingparam": "Paramètres nécessaires à la demande manquants.",
+       "rollback-missingrevision": "Impossible de charger les données de correction.",
        "cantrollback": "Impossible de révoquer la modification ;\nle dernier contributeur est le seul auteur de cette page.",
        "alreadyrolled": "Impossible de révoquer la dernière modification de la page « [[:$1]] » effectuée par [[User:$2|$2]] ([[User talk:$2|Discuter]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ;\nquelqu'un d'autre a déjà modifié ou révoqué la page.\n\nLa dernière modification de la page a été effectuée par [[User:$3|$3]] ([[User talk:$3|Discuter]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Le résumé de la modification était : <em>$1</em>.",
        "protect_expiry_invalid": "La date d'expiration est invalide.",
        "protect_expiry_old": "La date d'expiration est déjà passée.",
        "protect-unchain-permissions": "Déverrouiller davantage d’options de protection",
-       "protect-text": "Vous pouvez consulter et modifier le niveau de protection de la page '''$1'''.",
-       "protect-locked-blocked": "Vous ne pouvez pas modifier les niveaux de protection durant votre blocage.\nVoici les réglages actuels de la page '''$1''' :",
-       "protect-locked-dblock": "Le niveau de protection ne peut pas être modifié car la base de données est verrouillée.\nVoici les réglages actuels de la page '''$1''' :",
-       "protect-locked-access": "Vous n'avez pas les droits nécessaires pour modifier les niveaux de protection de pages.\nVoici les réglages actuels de la page '''$1''' :",
+       "protect-text": "Ici vous pouvez consulter et modifier le niveau de protection de la page <strong>$1</strong>.",
+       "protect-locked-blocked": "Vous ne pouvez pas modifier les niveaux de protection durant votre blocage.\nVoici les réglages actuels de la page <strong>$1</strong> :",
+       "protect-locked-dblock": "Les niveaux de protection ne peuvent pas être modifiés car la base de données est verrouillée.\nVoici les réglages actuels de la page <strong>$1</strong> :",
+       "protect-locked-access": "Vous n'avez pas les droits nécessaires pour modifier les niveaux de protection des pages.\nVoici les réglages actuels de la page <strong>$1<strong> :",
        "protect-cascadeon": "Cette page est protégée car elle est transcluse dans {{PLURAL:$1|la page suivante, qui a été protégée|les pages suivantes, qui ont été protégées}} avec l'option « protection en cascade » activée.\nLa modification du niveau de protection de cette page n'affectera pas la protection en cascade.",
        "protect-default": "Autoriser tous les utilisateurs",
        "protect-fallback": "Autoriser uniquement les utilisateurs avec le droit « $1 »",
        "protect-existing-expiry-infinity": "Délai d’expiration existant : infini",
        "protect-otherreason": "Motif autre ou supplémentaire :",
        "protect-otherreason-op": "Autre motif",
-       "protect-dropdown": "* Motifs de protection courants\n** Vandalisme excessif\n** Pourriels\n** Conflits de modifications contre-productives\n** Page à fort trafic",
+       "protect-dropdown": "* Motifs de protection courants\n** Vandalisme excessif\n** Pourriels excessifs\n** Conflits de modifications contre-productives\n** Page à fort trafic",
        "protect-edit-reasonlist": "Modifier les motifs de protection",
        "protect-expiry-options": "1 heure:1 hour,1 jour:1 day,1 semaine:1 week,2 semaines:2 weeks,1 mois:1 month,3 mois:3 months,6 mois:6 months,1 an:1 year,indéfiniment:infinite",
        "restriction-type": "Autorisation :",
        "restriction-level-all": "tout niveau",
        "undelete": "Voir les pages supprimées",
        "undeletepage": "Voir et restaurer des pages supprimées",
-       "undeletepagetitle": "'''La liste suivante contient des versions supprimées de [[:$1|$1]]'''.",
+       "undeletepagetitle": "<strong>La liste suivante contient des versions supprimées de [[:$1|$1]]</strong>.",
        "viewdeletedpage": "Voir les pages supprimées",
        "undeletepagetext": "{{PLURAL:$1|La page suivante a été supprimée et se trouve|Les pages suivantes ont été supprimées et se trouvent}} dans la base de données archive, d’où {{PLURAL:$1|elle peut|elles peuvent}} encore être restaurée{{PLURAL:$1||s}}.\nL’archive peut être nettoyée périodiquement.",
        "undelete-fieldset-title": "Restaurer les versions",
-       "undeleteextrahelp": "Pour restaurer l’historique complet de cette page, laissez toutes les cases décochées et cliquez sur '''''Restaurer'''''.\nPour effectuer une restauration partielle, cochez les cases correspondant aux versions à rétablir, puis cliquez sur '''''Restaurer'''''.",
+       "undeleteextrahelp": "Pour restaurer l’historique complet de cette page, laissez toutes les cases décochées et cliquez sur <strong><em>{{int:undeletebtn}}</em></strong>.\nPour effectuer une restauration partielle, cochez les cases correspondant aux versions à rétablir, puis cliquez sur <strong><em>{{int:undeletebtn}}</em></strong>.",
        "undeleterevisions": "$1 {{PLURAL:$1|révision supprimée|révisions supprimées}}",
-       "undeletehistory": "Si vous restaurez la page, toutes les versions seront replacées dans l’historique.\nSi une nouvelle page avec le même nom a été créée depuis la suppression, les versions restaurées apparaîtront dans l’historique antérieur et la version courante ne sera pas automatiquement remplacée.",
+       "undeletehistory": "Si vous restaurez la page, toutes les versions seront replacées dans l’historique.\nSi une nouvelle page avec le même nom a été créée depuis la suppression, les versions restaurées s’inséreront dans l’historique antérieur.",
        "undeleterevdel": "La restauration ne sera pas effectuée si, au final, la version la plus récente de la page ou du fichier reste partiellement supprimée.\nDans de tels cas, vous devez décocher ou démasquer les versions effacées les plus récentes (en tête de liste).",
        "undeletehistorynoadmin": "Cette page a été supprimée.\nLe motif de la suppression est indiqué dans le résumé ci-dessous, avec les détails des utilisateurs qui ont modifié la page avant sa suppression.\nLe contenu effectif de ces versions supprimées n’est accessible qu’aux administrateurs.",
        "undelete-revision": "Version supprimée de $1 (version du $4 à $5) par $3 :",
        "undeletedrevisions-files": "$1 version{{PLURAL:$1||s}} et $2 fichier{{PLURAL:$2||s}} restauré{{PLURAL:$2||s}}",
        "undeletedfiles": "$1 {{PLURAL:$1|fichier restauré|fichiers restaurés}}",
        "cannotundelete": "Certaines ou toutes les restitutions ont échoué:\n$1",
-       "undeletedpage": "'''La page $1 a été restaurée.'''\n\nConsultez le [[Special:Log/delete|journal des suppressions]] pour obtenir la liste des récentes suppressions et restaurations.",
+       "undeletedpage": "<strong>La page $1 a été restaurée.</strong>\n\nConsultez le [[Special:Log/delete|journal des suppressions]] pour obtenir la liste des récentes suppressions et restaurations.",
        "undelete-header": "Consultez le [[Special:Log/delete|journal des suppressions]] pour lister les pages récemment supprimées.",
        "undelete-search-title": "Rechercher les pages supprimées",
-       "undelete-search-box": "Rechercher des pages supprimées",
+       "undelete-search-box": "Rechercher les pages supprimées",
        "undelete-search-prefix": "Montrer les pages commençant par :",
        "undelete-search-submit": "Rechercher",
        "undelete-no-results": "Aucune page correspondante n’a été trouvée dans les archives de suppression.",
        "sp-contributions-logs": "journaux",
        "sp-contributions-talk": "discuter",
        "sp-contributions-userrights": "gérer les droits",
-       "sp-contributions-blocked-notice": "Cet utilisateur est actuellement bloqué. La dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
+       "sp-contributions-blocked-notice": "Cet utilisateur est actuellement bloqué. \nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
        "sp-contributions-blocked-notice-anon": "Cette adresse IP est actuellement bloquée.\nLa dernière entrée du journal des blocages est indiquée ci-dessous à titre d'information :",
        "sp-contributions-search": "Rechercher les contributions",
        "sp-contributions-username": "Adresse IP ou nom d'utilisateur :",
        "whatlinkshere": "Pages liées",
        "whatlinkshere-title": "Pages qui pointent vers « $1 »",
        "whatlinkshere-page": "Page :",
-       "linkshere": "Les pages ci-dessous contiennent un lien vers '''[[:$1]]''' :",
-       "nolinkshere": "Aucune page ne contient de lien vers '''[[:$1]]'''.",
-       "nolinkshere-ns": "Aucune page ne contient de lien vers '''[[:$1]]''' dans l'espace de noms choisi.",
+       "linkshere": "Les pages ci-dessous contiennent un lien vers <strong>[[:$1]]</strong> :",
+       "nolinkshere": "Aucune page ne contient de lien vers <strong>[[:$1]]</strong>.",
+       "nolinkshere-ns": "Aucune page ne contient de lien vers <strong>[[:$1]]</strong> dans l'espace de noms choisi.",
        "isredirect": "page de redirection",
        "istemplate": "inclusion",
        "isimage": "lien vers le fichier",
        "ipb-hardblock": "Empêcher les utilisateurs connectés de modifier en utilisant cette adresse IP",
        "ipbcreateaccount": "Empêcher la création de compte",
        "ipbemailban": "Empêcher l'utilisateur d'envoyer des courriels",
-       "ipbenableautoblock": "Bloquer automatiquement la dernière adresse IP utilisée par l'utilisateur et toutes ses IPs ultérieures qu'il pourrait essayer",
-       "ipbsubmit": "Bloquer",
+       "ipbenableautoblock": "Bloquer automatiquement la dernière adresse IP utilisée par cet utilisateur et toutes ses IPs ultérieures qu'il pourrait essayer",
+       "ipbsubmit": "Bloquer cet utilisateur",
        "ipbother": "Autre durée :",
        "ipboptions": "2 heures:2 hours,1 jour:1 day,3 jours:3 days,1 semaine:1 week,2 semaines:2 weeks,1 mois:1 month,3 mois:3 months,6 mois:6 months,1 an:1 year,indéfiniment:infinite",
        "ipbhidename": "Masquer le nom d'utilisateur des modifications et des listes",
        "ipbwatchuser": "Suivre les pages utilisateur et de discussion de cet utilisateur",
        "ipb-disableusertalk": "Empêcher l'utilisateur de modifier sa page de discussion pendant le blocage",
-       "ipb-change-block": "Modifier les paramètres de blocage",
+       "ipb-change-block": "Bloquer à nouveau l'utilisateur avec ces paramètres",
        "ipb-confirm": "Confirmer le blocage",
        "badipaddress": "Adresse IP incorrecte",
        "blockipsuccesssub": "Blocage réussi",
        "ipb-blocklist-contribs": "Contributions pour {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "$1 restant",
        "unblockip": "Débloquer un utilisateur ou une adresse IP",
-       "unblockiptext": "Utilisez le formulaire ci-dessous pour redonner les droits d’écriture à une adresse IP ou un nom d’utilisateur.",
+       "unblockiptext": "Utilisez le formulaire ci-dessous pour redonner les droits d’écriture à une adresse IP ou un nom d’utilisateur qui a été bloqué auparavant.",
        "ipusubmit": "Supprimer ce blocage",
        "unblocked": "[[User:$1|$1]] a été débloqué{{GENDER:$1||e}}",
        "unblocked-range": "Le compte $1 a été débloqué",
        "blocklist-userblocks": "Masquer les blocages de comptes",
        "blocklist-tempblocks": "Masquer les blocages temporaires",
        "blocklist-addressblocks": "Masquer les blocages d’adresses IP uniques",
-       "blocklist-rangeblocks": "Masquer les blocs de portée",
+       "blocklist-rangeblocks": "Masquer les blocages sur intervalles",
        "blocklist-timestamp": "Date et heure",
        "blocklist-target": "Cible",
        "blocklist-expiry": "Date d’expiration",
        "noautoblockblock": "blocage automatique désactivé",
        "createaccountblock": "création de compte bloquée",
        "emailblock": "courriel bloqué",
-       "blocklist-nousertalk": "ne peut modifier sa propre page de discussion",
+       "blocklist-nousertalk": "ne peut pas modifier sa propre page de discussion",
        "ipblocklist-empty": "La liste des adresses IP bloquées est actuellement vide.",
        "ipblocklist-no-results": "L'adresse IP ou l'utilisateur demandé n'est pas bloqué.",
        "blocklink": "bloquer",
        "unblocklink": "débloquer",
        "change-blocklink": "modifier le blocage",
        "contribslink": "contributions",
-       "emaillink": "Envoyer un courriel",
+       "emaillink": "envoyer un courriel",
        "autoblocker": "Vous avez été bloqué automatiquement parce que votre adresse IP a été récemment utilisée par « [[User:$1|$1]] ».\nLe motif fourni pour le blocage de $1 est « $2 »",
        "blocklogpage": "Journal des blocages",
-       "blocklog-showlog": "Cet utilisateur a été bloqué précédemment. Le journal des blocages est disponible ci-dessous :",
-       "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et masqué précédemment. Le journal des masquages est disponible ci-dessous :",
+       "blocklog-showlog": "Cet utilisateur a été bloqué précédemment. \nLe journal des blocages est disponible ci-dessous :",
+       "blocklog-showsuppresslog": "Cet utilisateur a été bloqué et masqué précédemment. \nLe journal des masquages est disponible ci-dessous :",
        "blocklogentry": "a bloqué [[$1]] ; expiration : $2 $3",
        "reblock-logentry": "a modifié les paramètres du blocage de [[$1]] avec une expiration au $2 $3",
        "blocklogtext": "Ceci est le journal des actions de blocage et déblocage d’utilisateurs.\nLes adresses IP automatiquement bloquées ne sont pas listées.\nConsultez la [[Special:BlockList|liste des blocages]] pour voir les bannissements et blocages effectivement en cours.",
        "ipb_cant_unblock": "Erreur : identifiant de blocage $1 non trouvé.\nIl est possible qu'un déblocage ait déjà été effectué.",
        "ipb_blocked_as_range": "Erreur : l'adresse IP $1 n'est pas bloquée directement et ne peut donc pas être débloquée.\nElle fait cependant partie de la plage $2 qui, elle, peut être débloquée.",
        "ip_range_invalid": "Plage d’adresses IP incorrecte.",
-       "ip_range_toolarge": "Les blocages de plages plus grandes que /$1 ne sont pas autorisées.",
+       "ip_range_toolarge": "Les plages de blocage plus grandes que /$1 ne sont pas autorisées.",
        "proxyblocker": "Bloqueur de mandataires",
        "proxyblockreason": "Votre adresse IP a été bloquée car il s'agit d'un mandataire ouvert.\nVeuillez contacter votre fournisseur d'accès Internet ou votre support technique et l'informer de ce sérieux problème de sécurité.",
        "sorbsreason": "Votre adresse IP est listée comme mandataire ouvert dans le DNSBL utilisé par {{SITENAME}}.",
        "sorbs_create_account_reason": "Votre adresse IP est listée comme mandataire ouvert dans le DNSBL utilisé par {{SITENAME}}.\nVous ne pouvez pas créer un compte.",
        "xffblockreason": "Une adresse IP dans l'en-tête X-Forwarded-For, soit la vôtre ou celle d'un serveur proxy que vous utilisez, a été bloquée. La raison du blocage initial est : $1",
-       "cant-see-hidden-user": "L’utilisateur que vous tentez de bloquer a déjà été bloqué et masqué. N’ayant pas le droit ''hideuser'', vous ne pouvez pas voir ou modifier le blocage de cet utilisateur.",
+       "cant-see-hidden-user": "L’utilisateur que vous tentez de bloquer a déjà été bloqué et masqué. \nN’ayant pas le droit de masquer des utilisateurs, vous ne pouvez pas voir ou modifier le blocage de cet utilisateur.",
        "ipbblocked": "Vous ne pouvez pas bloquer ou débloquer d'autres utilisateurs, parce que vous êtes vous-même bloqué{{GENDER:||e}}.",
        "ipbnounblockself": "Vous n'êtes pas autorisé{{GENDER:||e}} à vous débloquer vous-même",
        "lockdb": "Verrouiller la base de données",
        "unlockdbsuccesssub": "Verrouillage de la base de données supprimé",
        "lockdbsuccesstext": "La base de données a été verrouillée.<br />\nN'oubliez pas de la [[Special:UnlockDB|déverrouiller]] lorsque vous aurez terminé votre opération de maintenance.",
        "unlockdbsuccesstext": "La base de données a été déverrouillée.",
-       "lockfilenotwritable": "Le fichier de verrouillage de la base de données n'est pas inscriptible.\nPour bloquer ou débloquer la base de données, il doit être accessible par le serveur web.",
+       "lockfilenotwritable": "Le fichier de verrouillage de la base de données n'est pas inscriptible.\nPour bloquer ou débloquer la base de données, il doit être accessible en écriture par le serveur web.",
        "databaselocked": "La base de données est déjà verrouillée.",
        "databasenotlocked": "La base de données n'est pas verrouillée.",
-       "lockedbyandtime": "(par $1 le $2 à $3)",
+       "lockedbyandtime": "(par {{GENDER:$1|$1}} le $2 à $3)",
        "move-page": "Renommer $1",
        "move-page-legend": "Renommer une page",
        "movepagetext": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L’ancien titre deviendra une page de redirection vers le nouveau titre. \nVous pouvez mettre à jour automatiquement les redirections qui pointent vers le titre original. \nSi vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> renommée s’il existe déjà une page portant le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. \nCela signifie que vous pouvez de nouveau renommer une page vers sa position d’origine si vous avez fait une erreur et que vous ne pouvez pas écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’avoir compris les conséquences de votre démarche avant de continuer.",
        "movepagetext-noredirectfixer": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.\nL’ancien titre deviendra une page de redirection vers le nouveau titre.\nVérifiez bien les [[Special:DoubleRedirects|doubles redirections]] ou les [[Special:BrokenRedirects|redirections cassées]].\nVous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> déplacée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est soit vide, soit une simple redirection. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné, et il est impossible d’écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
        "movepagetalktext": "Si vous cochez cette case, la page de discussion associée sera automatiquement renommée, à moins qu’une page de discussion non vide existe déjà sous ce nouveau nom.\n\nDans ce cas, vous devrez renommer ou fusionner cette page de discussion manuellement si vous le désirez.",
-       "moveuserpage-warning": "'''Attention :''' Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur '''ne''' sera '''pas''' renommé.",
+       "moveuserpage-warning": "<strong>Attention :</strong> Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur <em>ne</em> sera <em>pas</em> renommé.",
        "movecategorypage-warning": "<strong>Avertissement :</strong> Vous êtes sur le point de renommer une page de catégorie. Veuillez noter que seule la catégorie sera renommée et <em>qu’aucune</em> des pages de l’ancienne catégorie ne sera transférée dans la nouvelle.",
        "movenologintext": "Pour pouvoir renommer une page, vous devez être [[Special:UserLogin|identifié{{GENDER:||e}}]] avec un compte utilisateur enregistré et d'ancienneté suffisante.",
        "movenotallowed": "Vous n'avez pas la permission de renommer les pages.",
        "movenotallowedfile": "Vous n'avez pas la permission de renommer les fichiers.",
-       "cant-move-user-page": "Vous n’avez pas la permission de renommer les pages principales d’utilisateurs.",
-       "cant-move-to-user-page": "Vous n’avez pas la permission de renommer une page vers une page utilisateur (à l’exception d’une sous-page).",
+       "cant-move-user-page": "Vous n’avez pas la permission de renommer les pages principales des utilisateurs (sauf les sous-pages).",
+       "cant-move-to-user-page": "Vous n’avez pas la permission de renommer une page vers une page utilisateur (mais vous pouvez le faire vers une sous-page utilisateur).",
        "cant-move-category-page": "Vous n'avez pas la permis de renommer les pages de catégorie.",
        "cant-move-to-category-page": "Vous n'avez pas la permission de renommer une page vers une page de catégorie.",
        "newtitle": "Nouveau titre :",
index 7e69455..2765143 100644 (file)
        "minoredit": "Mionathrú é seo",
        "watchthis": "Déan faire ar an lch seo",
        "savearticle": "Sábháil an lch",
+       "publishpage": "Foilsigh leathanach",
        "preview": "Réamhamharc",
        "showpreview": "Taispeáin réamhamharc",
        "showdiff": "Taispeáin athruithe",
        "recreate-moveddeleted-warn": "'''Rabhadh: Tá tú ag athchruthú leathanaigh a scriosadh cheana.'''\n\nAn bhfuil tú cinnte go bhfuil sé oiriúnach an leathanach seo a cur in eagar?\nCuirtear an loga scriosta ar fáil anseo mar áis:",
        "log-fulllog": "Féach ar an logchomhad iomlán",
        "undo-summary": "Cealaíodh athrú $1 le [[Special:Contributions/$2|$2]] ([[User talk:$2|plé]])",
-       "cantcreateaccounttitle": "Ní féidir cuntas a chruthú",
        "viewpagelogs": "Féach ar logaí faoin leathanach seo",
        "nohistory": "Níl aon stáir athraithe ag an leathanach seo.",
        "currentrev": "Leagan reatha",
        "tooltip-ca-nstab-category": "Féach ar an leathanach catagóire",
        "tooltip-minoredit": "Déan mionathrú den athrú seo",
        "tooltip-save": "Sábháil do chuid athruithe",
+       "tooltip-publish": "Foilsigh do chuid athruithe",
        "tooltip-preview": "Réamhamharc ar do chuid athruithe; úsáid an gné seo roimh a shábhálaíonn tú!",
        "tooltip-diff": "Taispeáin na difríochtaí áirithe a rinne tú don téacs",
        "tooltip-compareselectedversions": "Féach na difríochtaí idir an dhá leagain roghnaithe den leathanach seo.",
        "exif-gpsspeed-n": "Muirmhílte",
        "exif-gpsdirection-t": "Fíorthreo",
        "exif-gpsdirection-m": "Treo maighnéadach",
+       "exif-dc-publisher": "Foilsitheoir",
        "namespacesall": "iad uile",
        "monthsall": "gach mí",
        "confirmemail": "Deimhnigh do ríomhsheoladh",
index f76e5b8..e6907d2 100644 (file)
        "rollbacklinkcount-morethan": "reverter máis de $1 {{PLURAL:$1|edición|edicións}}",
        "rollbackfailed": "Houbo un erro ao reverter as edicións",
        "rollback-missingparam": "Faltan parámetros obrigatorios na solicitude.",
+       "rollback-missingrevision": "Non se poden cargar datos da revisión.",
        "cantrollback": "Non se pode desfacer a edición; o último colaborador é o único autor desta páxina.",
        "alreadyrolled": "Non se pode desfacer a edición en \"[[:$1]]\" feita por [[User:$2|$2]] ([[User talk:$2|conversa]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); alguén máis editou ou desfixo os cambios desta páxina.\n\nA última edición fíxoa [[User:$3|$3]] ([[User talk:$3|conversa]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "O resumo de edición foi: <em>$1</em>.",
        "linkaccounts-submit": "Vincular contas",
        "unlinkaccounts": "Desvincular contas",
        "unlinkaccounts-success": "A conta foi desvinculada.",
-       "authenticationdatachange-ignored": "Os cambios de datos de autenticación non foron xerados. Está configurado o provedor?"
+       "authenticationdatachange-ignored": "Os cambios de datos de autenticación non foron xerados. Está configurado o provedor?",
+       "userjsispublic": "Lembre: As subpáxinas JavaScript non deberían conter datos confidenciais porque outros usuarios poden velos.",
+       "usercssispublic": "Lembre: As subpáxinas CSS non deberían conter datos confidenciais porque outros usuarios poden velos."
 }
index 80cf567..47d668d 100644 (file)
        "alllogstext": "{{SITENAME}} ના લોગનો સંયુક્ત વર્ણન.\nતમે લોગનો પ્રકાર,સભ્ય નામ અથવા અસરગ્રસ્ત પાના આદિ પસંદ કરી તમારી યાદિ ટૂંકાવી શકો.",
        "logempty": "લોગમાં આને મળતી કોઇ વસ્તુ નથી",
        "log-title-wildcard": "આ શબ્દો દ્વારા શરૂ થનાર શીર્ષકો શોધો",
-       "showhideselectedlogentries": "પસàª\82દàª\97à«\80નà«\80 àª²à«\8bàª\97 àª¨à«\8bàª\82ધણà«\80àª\93 àª¬àª¤àª¾àªµà«\8b/àª\9bà«\82પાવો",
+       "showhideselectedlogentries": "પસàª\82દàª\97à«\80નà«\80 àª²à«\8bàª\97 àª¨à«\8bàª\82ધણà«\80àª\93 àª¬àª¤àª¾àªµà«\8b/àª\9bà«\81પાવો",
        "allpages": "બધા પાના",
        "nextpage": "આગળનું પાનું ($1)",
        "prevpage": "પાછળનું પાનું ($1)",
index 7f73d57..e5c20a7 100644 (file)
        "sharedupload-desc-edit": "זהו קובץ מתוך $1 וניתן להשתמש בו גם במיזמים אחרים.\nניתן לערוך את התקציר שלו ב[$2 דף תיאור הקובץ] שם.",
        "sharedupload-desc-create": "זהו קובץ מתוך $1 וניתן להשתמש בו גם במיזמים אחרים.\nניתן לערוך את התקציר שלו ב[$2 דף תיאור הקובץ] שם.",
        "filepage-nofile": "לא קיים קובץ בשם זה.",
-       "filepage-nofile-link": "לא קיים קובץ בשם זה, אך באפשרותך [$1 להעלות אחד].",
+       "filepage-nofile-link": "לא קיים קובץ בשם זה, אך באפשרותך [$1 להעלותו].",
        "uploadnewversion-linktext": "העלאת גרסה חדשה של קובץ זה",
        "shared-repo-from": "מתוך $1",
        "shared-repo": "מקום איחסון משותף",
        "emailccsubject": "העתק של הודעתך למשתמש $1: $2",
        "emailsent": "הדואר נשלח",
        "emailsenttext": "הודעת הדואר האלקטרוני שלך נשלחה.",
-       "emailuserfooter": "$1 {{GENDER:$1|שלח|שלחה}} את הדוא\"ל הזה ל{{GRAMMAR:תחילית|$2}} באמצעות התכונה \"{{int:emailuser}}\" ב{{GRAMMAR:תחילית|{{SITENAME}}}}.",
+       "emailuserfooter": "$1 {{GENDER:$1|שלח|שלחה}} את הדוא\"ל הזה ל{{GENDER:$2|משתמש|משתמשת}} $2 באמצעות התכונה \"{{int:emailuser}}\" באתר {{SITENAME}}.",
        "usermessage-summary": "השארת הודעת מערכת.",
        "usermessage-editor": "שולח הודעות המערכת",
        "watchlist": "רשימת המעקב",
        "rollbacklinkcount-morethan": "שחזור יותר מ{{PLURAL:$1|עריכה אחת|־$1 עריכות}}",
        "rollbackfailed": "השחזור נכשל",
        "rollback-missingparam": "חסרים פרמטרים נדרשים להגשת הבקשה.",
+       "rollback-missingrevision": "לא ניתן לטעון את המידע על הגרסה.",
        "cantrollback": "לא ניתן לשחזר את העריכה;\nהתורם האחרון הוא היחיד שכתב בדף זה.",
        "alreadyrolled": "לא ניתן לשחזר את העריכה של [[User:$2|$2]] ([[User talk:$2|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) בדף [[:$1]]; הדף כבר נערך או שוחזר.\n\nהעריכה האחרונה הייתה של [[User:$3|$3]] ([[User talk:$3|שיחה]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "תקציר העריכה היה: <em>$1</em>.",
        "linkaccounts-submit": "קישור החשבונות",
        "unlinkaccounts": "ביטול הקישור של החשבונות",
        "unlinkaccounts-success": "קישור החשבון בוטל.",
-       "authenticationdatachange-ignored": "השינוי בנתוני האימות לא הצליח. ייתכן שלא הוגדר ספק."
+       "authenticationdatachange-ignored": "השינוי בנתוני האימות לא הצליח. ייתכן שלא הוגדר ספק.",
+       "userjsispublic": "שימו לב: משתמשים אחרים יכולים לצפות בדפי ה־JavaScript שלכם, ולכן אין לכלול בהם מידע סודי.",
+       "usercssispublic": "שימו לב: משתמשים אחרים יכולים לצפות בדפי ה־CSS שלכם, ולכן אין לכלול בהם מידע סודי."
 }
index d241144..db69923 100644 (file)
        "grant-highvolume": "nagy mennyiségű szerkesztés",
        "grant-oversight": "felhasználók és lapváltozatok elrejtése",
        "grant-patrol": "szerkesztések ellenőrzése",
+       "grant-privateinfo": "Hozzáférés a személyes információkhoz",
        "grant-protect": "lapok védelme és védelem feloldása",
        "grant-rollback": "szerkesztések gyors visszaállítása",
        "grant-sendemail": "e-mail küldése más felhasználóknak",
        "upload-too-many-redirects": "Az URL túl sokszor volt átirányítva",
        "upload-http-error": "HTTP-hiba történt: $1",
        "upload-copy-upload-invalid-domain": "Másolás nem engedélyezett ebből a tartományból.",
+       "upload-dialog-disabled": "Fájl feltöltés ezzel a párbeszéddel tiltott ezen a wikin.",
        "upload-dialog-title": "Fájl feltöltése",
        "upload-dialog-button-cancel": "Mégse",
        "upload-dialog-button-done": "Kész",
        "tags-deactivate": "deaktiválás",
        "tags-hitcount": "{{PLURAL:$1|Egy|$1}} változtatás",
        "tags-manage-no-permission": "Nincs engedélyed a változtatások címkéinek kezeléséhez.",
+       "tags-manage-blocked": "Nem tudja kezelni a változás kategóriát, amíg blokkolt.",
        "tags-create-heading": "Új címke létrehozása",
        "tags-create-explanation": "Alapértelmezés szerint az újonnan létrehozott címkék felhasználók és botok által manuálisan hozzáadhatók lesznek.",
        "tags-create-tag-name": "Címke neve:",
        "tags-delete-not-found": "A(z) „$1” címke nem létezik.",
        "tags-delete-too-many-uses": "A(z) „$1” címke több mint $2 lapváltoztatásban szerepel, ezáltal nem törölhető.",
        "tags-delete-warnings-after-delete": "A(z) „$1” címke sikeresen törölve lett, de a következő {{PLURAL:$2|figyelmeztetést|figyelmeztetéseket}} találtam:",
+       "tags-delete-no-permission": "Nincs engedélye a változás címkéinek törléséhez.",
        "tags-activate-title": "Címke aktiválása",
        "tags-activate-question": "Éppen a(z) „$1” címke aktiválására készülsz.",
        "tags-activate-reason": "Indoklás:",
        "log-action-filter-move": "Átnevezés típusa:",
        "log-action-filter-patrol": "Járőrözés típusa:",
        "log-action-filter-protect": "Lapvédelem típusa:",
+       "log-action-filter-upload": "Feltöltés típusa:",
        "log-action-filter-all": "Mind",
        "log-action-filter-block-block": "Blokk",
        "log-action-filter-block-reblock": "Blokk módosítása",
        "log-action-filter-delete-delete": "Laptörlés",
        "log-action-filter-delete-restore": "Visszaállítás",
        "log-action-filter-delete-event": "Naplótörlés",
+       "log-action-filter-managetags-create": "Címke létrehozása",
+       "log-action-filter-managetags-delete": "Címke törlése",
+       "log-action-filter-managetags-activate": "Tag aktiválása",
+       "log-action-filter-newusers-create": "Létrehozás által anonim felhasználó által",
+       "log-action-filter-newusers-create2": "Létrehozás regisztrált felhasználó által",
        "log-action-filter-newusers-autocreate": "Automatikus létrehozás",
+       "log-action-filter-newusers-byemail": "Létrehozás jelszóval, e-mail által küldve",
        "log-action-filter-protect-protect": "Lapvédelem",
        "log-action-filter-protect-unprotect": "Védelem feloldása",
+       "log-action-filter-rights-rights": "Kézi módosítás",
        "log-action-filter-upload-upload": "Új feltöltés",
+       "authmanager-create-disabled": "Új fiók létrehozása tiltva.",
+       "authmanager-create-from-login": "A fiókja létrehozásához, kérjük, töltse ki az alábbi mezőket.",
+       "authmanager-create-not-in-progress": "Fiók létrehozása nincs folyamatban, vagy a folyamat adatai elvesztek. Kérjük, indítsa újra az elejétől.",
+       "authmanager-authplugin-setpass-failed-title": "Jelszó megváltoztatása nem sikerült",
+       "authmanager-authplugin-setpass-failed-message": "A hitelesítés beépülője megtagadta a jelszó módosítását.",
+       "authmanager-authplugin-create-fail": "A hitelesítés beépülője megtagadta a fiók létrehozását.",
+       "authmanager-authplugin-setpass-denied": "A hitelesítés beépülője nem teszi lehetővé a jelszó megváltoztatását.",
+       "authmanager-authplugin-setpass-bad-domain": "Érvénytelen domain.",
+       "authmanager-autocreate-noperm": "Az automatikus fióklétrehozás nem engedélyezett.",
+       "authmanager-autocreate-exception": "A fiókok automatikus létrehozását átmenetileg letiltottuk a korábbi hibák miatt.",
+       "authmanager-userdoesnotexist": "A(z) „$1” felhasználó nincs regisztrálva.",
+       "authmanager-retype-help": "Jelszó még egyszer a megerősítéshez.",
+       "authmanager-email-label": "E-mail",
+       "authmanager-email-help": "E-mail-cím",
+       "authmanager-realname-label": "Valódi név",
+       "authmanager-realname-help": "A felhasználó valódi neve",
+       "authmanager-provider-password": "Jelszó alapú hitelesítés",
+       "authmanager-provider-password-domain": "Jelszó - domain-alapú hitelesítés",
+       "authmanager-provider-temporarypassword": "Ideiglenes jelszó",
        "authprovider-resetpass-skip-label": "Kihagy",
        "cannotauth-not-allowed-title": "Engedély megtagadva",
-       "credentialsform-account": "Fiók neve:"
+       "credentialsform-account": "Fiók neve:",
+       "cannotlink-no-provider-title": "Nincsenek csatolható fiókok",
+       "cannotlink-no-provider": "Nincsenek csatolható fiókok.",
+       "linkaccounts": "A fiókok csatolása",
+       "linkaccounts-success-text": "A fiók csatolva."
 }
index 0cca8aa..a005dcc 100644 (file)
        "rightslogtext": "Daytoy ket listaan dagiti sinukatan a karbengan ti agar-aramat.",
        "action-read": "agbasa iti datoy a panid",
        "action-edit": "agurnos iti daytoy a panid",
-       "action-createpage": "partuaten daytoy a panid",
+       "action-createpage": "agpartuat iti daytoy a panid",
        "action-createtalk": "partuaten daytoy a pagtungtungan a panid",
        "action-createaccount": "agpartuat iti pakabilangan daytoy nga agar-aramat",
        "action-autocreateaccount": "automatiko a partuaten daytoy nga akinruar a pakabilangan ti agar-aramat",
index b807488..184f0cb 100644 (file)
        "rollbacklinkcount-morethan": "rollback di più di {{PLURAL:$1|una modifica|$1 modifiche}}",
        "rollbackfailed": "Rollback fallito",
        "rollback-missingparam": "Parametri obbligatori mancanti nella richiesta.",
+       "rollback-missingrevision": "Impossibile caricare i dati della versione.",
        "cantrollback": "Impossibile annullare le modifiche; l'utente che le ha effettuate è l'unico ad aver contribuito alla pagina.",
        "alreadyrolled": "Non è possibile annullare le modifiche apportate alla pagina [[:$1]] da parte di [[User:$2|$2]] ([[User talk:$2|discussione]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); un altro utente ha già modificato la pagina oppure ha effettuato il rollback.\n\nLa modifica più recente alla pagina è stata apportata da [[User:$3|$3]] ([[User talk:$3|discussione]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "L'oggetto della modifica era: <em>$1</em>.",
index f70f581..3aabbe6 100644 (file)
        "userjsyoucanpreview": "'''Tips:''' Gunakna tombol \"{{int:showpreview}}\" kanggo ngetès JavaScript anyar panjenengan sadurungé disimpen.",
        "usercsspreview": "'''Pèngeten yèn panjenengan namung mirsani pratilik CSS panjenengan.''''\n'''Pratilik iku durung kasimpen!'''",
        "userjspreview": "'''Pèngeten yèn sing panjenengan pirsani namung pratilik JavaScript panjenengan, lan menawa pratilik iku dèrèng kasimpen!'''",
-       "sitecsspreview": "'''Èling yèn Sampéyan mung ndelok pratayang CSS iki.'''\n'''Iki durung disimpen!'''",
-       "sitejspreview": "'''Èling yèn Sampéyan mung ndelok pratayang kodhé JavaScript iki.'''\n'''Iki durung disimpen!'''",
+       "sitecsspreview": "<strong>Élinga yèn Sampéyan mung mratuduh CSS iki.\nIki durung kasimpen!</strong>",
+       "sitejspreview": "<strong>Élinga yèn Sampéyan mung mratuduh kodhé JavaScript iki.\nIki durung kasimpen!</strong>",
        "userinvalidcssjstitle": "'''Pènget:''' Kulit \"$1\" ora ditemokaké. Muga dipèngeti yèn kaca .css lan .js nggunakaké huruf cilik, conto {{ns:user}}:Foo/vector.css lan dudu {{ns:user}}:Foo/Vector.css.",
        "updated": "(Kaanyaran)",
        "note": "<strong>Cathetan:</strong>",
-       "previewnote": "'''Èling yèn Sampéyan mung ndelok pratayang.'''\nOwahan Sampéyan durung kasimpen!",
+       "previewnote": "<strong>Élinga yèn iki mung pratuduh.</strong>\nOwahanmu durung kasimpen!",
        "continue-editing": "Menyang pambesutan",
        "previewconflict": "Pratilik iki nuduhaké tèks ing bagian dhuwur kothak suntingan tèks kayadéné bakal katon yèn panjenengan bakal simpen.",
        "session_fail_preview": "'''Nuwun sèwu, suntingan panjenengan ora bisa diolah amarga dhata sèsi kabusak.\nCoba kirim dhata manèh. Yèn tetep ora bisa, coba log metua lan mlebu log manèh.''''''Amerga wiki iki marengaké panggunan kodhe HTML mentah, mula pratilik didhelikaké minangka pancegahan marang serangan JavaScript.'''\n'''Menawa iki sawijining usaha panyuntingan sing sah, mangga dicoba manèh.\nYèn isih tetep ora kasil, cobanen metu log lan mlebu manèh.'''",
        "rev-delundel": "Owah kasatmatan",
        "rev-showdeleted": "tuduhaké",
        "revisiondelete": "Busak/batal busak revisi",
-       "revdelete-nooldid-title": "Target revisi ora ditemokaké",
+       "revdelete-nooldid-title": "Rèvisi tujuan ora sah",
        "revdelete-nooldid-text": "Panjenengan durung mènèhi target revisi kanggo nglakoni fungsi iki.",
        "revdelete-no-file": "Berkas sing dituju ora ana.",
        "revdelete-show-file-confirm": "Apa panjenengan yakin arep mirsani révisi sing wis kabusak saka berkas \"<nowiki>$1</nowiki>\" ing $2, jam $3?",
        "mergehistory-fail": "Ora bisa nggabung sajarah, coba dipriksa manèh kacané lan paramèter wektuné.",
        "mergehistory-no-source": "Kaca sumber $1 ora ana.",
        "mergehistory-no-destination": "Kaca paran $1 ora ana.",
-       "mergehistory-invalid-source": "Irah-irahan kaca sumber kudu irah-irahan utawa judhul sing bener.",
-       "mergehistory-invalid-destination": "Irah-irahan kaca tujuan kudu irah-irahan utawa judhul sing bener.",
+       "mergehistory-invalid-source": "Kaca sumber kudu asesirah sing sah.",
+       "mergehistory-invalid-destination": "Kaca tujuan kudu asesirah sing sah.",
        "mergehistory-autocomment": "Nggabung [[:$1]] menyang [[:$2]]",
        "mergehistory-comment": "Nggabung [[:$1]] menyang [[:$2]]: $3",
        "mergehistory-same-destination": "Jeneng kaca sumber lan tujuan ora kena padha",
        "difference-missing-revision": "{{PLURAL:$2|Sak pambenahan|$2 pambenahan}} saka prabédan iki ($1) {{PLURAL:$2|ora ditemokaké|ora ditemokaké}}.\n\nIki biasané kasebab pranala prabedan sing wis ora kanggo saka kaca isi wis dibusak.\nRinciané bisa ditemokaké nèng [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log busak].",
        "searchresults": "Kasiling golèk",
        "searchresults-title": "Kasiling golèk \"$1\"",
-       "titlematches": "Irah-irahan artikel sing cocog",
+       "titlematches": "Sesirah kaca cocog",
        "textmatches": "Tèks artikel sing cocog",
        "notextmatches": "Ora ana tèks kaca sing cocog",
        "prevn": "{{PLURAL:$1|$1}} sadurungé",
        "prefs-timeoffset": "Format wektu",
        "prefs-advancedediting": "Pilihan sabanjuré",
        "prefs-editor": "Wong besut",
-       "prefs-preview": "Pratayang",
+       "prefs-preview": "Pratuduh",
        "prefs-advancedrc": "Opsi lanjutan",
        "prefs-advancedrendering": "Opsi lanjutan",
        "prefs-advancedsearchoptions": "Opsi lanjutan",
        "license": "Jenis lisènsi:",
        "license-header": "Pamalilah",
        "nolicense": "Durung ana sing dipilih",
-       "license-nopreview": "(Pratayang ora sumedya)",
+       "license-nopreview": "(Pratuduh ora sumadhiya)",
        "upload_source_url": " (sawijining URL absah sing bisa diaksès publik)",
        "upload_source_file": " (sawijining berkas ing komputeré panjenengan)",
        "listfiles-summary": "Kaca mirunggan iki nuduhaké kabèh barkas sing kaunggah.",
        "protectedpages-page": "Kaca",
        "protectedpages-expiry": "Kadaluwarsa",
        "protectedpages-reason": "Alesan",
-       "protectedtitles": "Irah-irahan sing direksa",
+       "protectedtitles": "Sesirah direksa",
        "protectedtitlesempty": "Ora ana irah-irahan utawa judhul sing direksa karo paramèter-paramèter iki.",
        "listusers": "Daftar panganggo",
        "listusers-editsonly": "Tampilaké mung panganggo sing nduwèni kontribusi",
        "nopagetitle": "Kaca tujuan ora ditemokaké",
        "nopagetext": "Kaca sing panjenengan tuju ora ditemokaké.",
        "pager-newer-n": "{{PLURAL:$1|1 luwih anyar|$1 luwih anyar}}",
-       "pager-older-n": "{{PLURAL:$1|1 sing luwih lawas|$1 sing luwih lawas}}",
+       "pager-older-n": "{{PLURAL:$1|1 luwih lawas|$1 luwih lawas}}",
        "suppress": "Dhelikaké",
        "querypage-disabled": "Kaca kusus iki dipatèni kanggo alesan kinerja.",
        "apisandbox": "Kothak wedhi API",
        "all-logs-page": "Kabèh log publik",
        "alllogstext": "Gabungan tampilam kabèh log sing ana ing {{SITENAME}}.\nPanjenengan bisa mbatesi tampilan kanthi milih jinis log, jeneng panganggo (sènsitif aksara gedhé/cilik), utawa kaca sing magepokan (uga sènsitif aksara gedhé/cilik).",
        "logempty": "Ora ditemokaké èntri log sing pas.",
-       "log-title-wildcard": "Golèk irah-irahan utawa judhul sing diawali mawa tèks kasebut",
+       "log-title-wildcard": "Golèk sesirah sing diwiwiti tulisan iki",
        "showhideselectedlogentries": "Tuduhalé/dhelikaké èntri log kapilih",
        "allpages": "Kabèh kaca",
        "nextpage": "Kaca sabanjuré ($1)",
        "linksearch-error": "''Wildcards'' namung bisa dienggo ing bagéyan awal saka jeneng host.",
        "listusersfrom": "Tuduhna panganggo sing diawali karo:",
        "listusers-submit": "Tuduhna",
-       "listusers-noresult": "Panganggo ora ditemokaké.",
+       "listusers-noresult": "Naraguna ora ana.",
        "listusers-blocked": "(diblokir)",
        "activeusers": "Dhaptar panganggo aktif",
        "activeusers-intro": "Iki daptar panganggo sing katon lakuné ing $1 {{PLURAL:$1|dina|dina}} kapungkur.",
        "activeusers-from": "Tampilna panganggo wiwit saka:",
        "activeusers-hidebots": "Delikna bot",
        "activeusers-hidesysops": "Delikna pangurus",
-       "activeusers-noresult": "Panganggo ora ditemokaké.",
+       "activeusers-noresult": "Naraguna ora ana.",
        "listgrouprights": "Hak-hak grup panganggo",
        "listgrouprights-summary": "Ing ngisor iki kapacak dhaftar grup panganggo sing didéfinisi ing wiki iki, kanthi hak-hak aksès gandhèngané.\nInformasi tambahan perkara hak-hak individual bisa ditemokaké ing [[{{MediaWiki:Listgrouprights-helppage}}|kéné]].",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Hak sing diidinaké</span>\n* <span class=\"listgrouprights-revoked\">Hak sing dijabel</span>",
        "deletedtext": "\"$1\" wis dibusak. \nDelenga $2 minangka rekamaning busak-busakan pungkasan.",
        "dellogpage": "Log busak",
        "dellogpagetext": "Ing ngisor iki kapacak log pambusakan kaca sing anyar dhéwé.",
-       "deletionlog": "Cathetan sing dibusak",
+       "deletionlog": "log busak",
        "reverted": "Dibalèkaké ing revisi sadurungé",
        "deletecomment": "Alesan:",
        "deleteotherreason": "Alesan liya utawa tambahan:",
        "imagetypemismatch": "Èkstènsi anyar berkas ora cocog karo jenisé",
        "imageinvalidfilename": "Jeneng berkas tujuan ora sah",
        "fix-double-redirects": "Dandani kabèh pangalihan gandha sing tumuju marang irah-irahan asli",
-       "move-leave-redirect": "Gawé pangalihan menyang irah-irahan anyar",
+       "move-leave-redirect": "Ungkur kaca alihan",
        "protectedpagemovewarning": "'''Pènget:''' Kaca iki wis dikunci dadi mung panganggo sing nduwé hak aksès pangurus baé sing bisa mindhahaké.\nCathetan entri pungkasan disadiakaké ing ngisor kanggo referensi:",
        "semiprotectedpagemovewarning": "'''Cathetan:''' Kaca iki wis direksa saéngga mung panganggo kadhaptar sing bisa mindhahaké.\nEntri cathetan pungkasan disadiakake ing ngisor kanggo referensi:",
        "move-over-sharedrepo": "[[:$1]] ana ing panyimpenan barengan. Ngalih barkas mawa sesirah iki bakal ngamblegi barkas barengan iku.",
        "allmessages-language": "Basa:",
        "allmessages-filter-submit": "Tumuju menyang",
        "thumbnail-more": "Gedhèkaké",
-       "filemissing": "Berkas ora ditemokaké",
+       "filemissing": "Barkas ilang",
        "thumbnail_error": "Kaluputan nalika nggawé gambar cilik (''thumbnail''): $1",
        "thumbnail_error_remote": "Peringatan kasalahan saka $1:\n$2",
        "djvu_page_error": "Kaca DjVu ana ing sajabaning ranggèhan (''range'')",
        "tooltip-recreate": "Gawéa kaca iki manèh senadyan tau dibusak",
        "tooltip-upload": "Miwiti pangunggahan",
        "tooltip-rollback": "Balèkaké besutan-besutan kaca iki déning sing pungkasan nyumbang sarana saklikan.",
-       "tooltip-undo": "Mbalèkaké révisi iki lan mbukak kothak panyuntingan jroning mode pratayang. Wènèhi kasempatan kanggo ngisi alesan ing kothak ringkesan.",
+       "tooltip-undo": "\"Wurungaké\" mbalèkaké besutan iki lan mbukak blangko besutan sarana modhe pratuduh. Alesan kena diwuwuhaké ing babagan ringkesan.",
        "tooltip-preferences-save": "Simpen préperensi",
        "tooltip-summary": "Isi tingkesan cendhak",
        "anonymous": "{{PLURAL:$1|Panganggo|panganggo}} anon ing {{SITENAME}}.",
        "table_pager_limit": "Tuduhna $1 entri per kaca",
        "table_pager_limit_label": "Barang per kaca:",
        "table_pager_limit_submit": "Golèk",
-       "table_pager_empty": "Ora ditemokaké",
+       "table_pager_empty": "Ora ana",
        "autosumm-blank": "Ngothongaké kaca",
        "autosumm-replace": "←Ngganti kaca karo '$1'",
        "autoredircomment": "←Ngalihaké menyang [[$1]]",
        "watchlistedit-normal-title": "Besut pawawangan",
        "watchlistedit-normal-legend": "Busak sesirah saka pawawangan",
        "watchlistedit-normal-explain": "Irah-irahan utawa judhul ing daftar pangawasan panjenengan kapacak ing ngisor iki.\nKanggo mbusak sawijining irah-irahan, kliken kothak ing pinggiré, lan banjur kliken \"Busak judhul\".\nPanjenengan uga bisa [[Special:EditWatchlist/raw|nyunting daftar mentah]].",
-       "watchlistedit-normal-submit": "Busak irah-irahan",
+       "watchlistedit-normal-submit": "Busak sesirah",
        "watchlistedit-normal-done": "Irah-irahan {{PLURAL:$1|siji|$1}} wis dibusak saka daftar pangawasan panjenengan:",
        "watchlistedit-raw-title": "Besut pawawangan wantahan",
        "watchlistedit-raw-legend": "Besut pawawangan wantahan",
        "watchlistedit-raw-explain": "Irah-irahan ing daftar pangawasan panjenengan kapacak ing ngisor iki, lan bisa diowahi mawa nambahaké utawa mbusak daftar; sairah-irahan saban barisé.\nYèn wis rampung, anyarana kaca daftar pangawasan iki.\nPanjenengan uga bisa [[Special:EditWatchlist|nganggo éditor standar panjenengan]].",
-       "watchlistedit-raw-titles": "Irah-irahan:",
+       "watchlistedit-raw-titles": "Sesirah:",
        "watchlistedit-raw-submit": "Anyari pawawangan",
        "watchlistedit-raw-done": "Pawawanganing sampéyan wis dianyari.",
-       "watchlistedit-raw-added": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} ditambahaké:",
-       "watchlistedit-raw-removed": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} diwetokaké:",
+       "watchlistedit-raw-added": "{{PLURAL:$1|1 sesirah|$1 sesirah}} ditambahaké:",
+       "watchlistedit-raw-removed": "{{PLURAL:$1|1 sesirah|$1 sesirah}} dibusak:",
        "watchlisttools-view": "Tuduhna owah-owahan sing ana gandhèngané",
        "watchlisttools-edit": "Deleng lan besut pawawangan",
        "watchlisttools-raw": "Besut pawawangan wantahan",
        "feedback-bugornote": "Yèn Sampéyan siap njelasaké masalah tèhnis kanthi rinci mangga [$1 laporaké bug].\nUtawa, Sampéyan bisa nganggo pormulir gampang ngisor. Tanggepan Sampéyan bakal ditambahaké nèng kaca \"[$3 $2]\", bebarengan karo jeneng panganggo Sampéyan lan pramban sing Sampéyan anggo.",
        "feedback-cancel": "Batal",
        "feedback-close": "Rampung",
+       "feedback-error-title": "Cacad",
        "feedback-error1": "Kasalahan: Asil ora dikenal saka API",
        "feedback-error2": "Cacad: Gagal mbesut",
        "feedback-error3": "Kasalahan: Ora ana tanggepan saka API",
        "limitreport-expensivefunctioncount": "Expensive parser function count",
        "expandtemplates": "Cithakan dikembangaké",
        "expand_templates_intro": "Kaca astaméwa iki njupuk sawetara tèks lan ngembangaké kabèh cithakan sajroning iku sacara rékursif.\nKaca iki uga ngembangaké fungsi parser kaya ta\n<nowiki>{{</nowiki>#language:…}}, lan variabel kaya ta\n<nowiki>{{</nowiki>CURRENTDAY}}&mdash;sajatiné mèh kabèh sing ana ing antara rong tandha kurung akolade.",
-       "expand_templates_title": "Irah-irahan kontèks, kanggo {{FULLPAGENAME}} lan sabanjuré:",
+       "expand_templates_title": "Sesirah kontèks, kanggo {{FULLPAGENAME}}, lsp.:",
        "expand_templates_input": "Tèks sumber:",
        "expand_templates_output": "Pituwas (kasil)",
        "expand_templates_xml_output": "Pituwas XML",
        "expand_templates_remove_nowiki": "Brèdèl tag <nowiki> nèng asilé",
        "expand_templates_generate_xml": "Tuduhna uwit parser XML",
        "expand_templates_generate_rawhtml": "Show raw HTML",
-       "expand_templates_preview": "Pratayang",
+       "expand_templates_preview": "Pratuduh",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Latin pepak",
        "special-characters-group-ipa": "IPA",
index 8abca6a..219b526 100644 (file)
        "botpasswords-label-cancel": "Bıtexelne",
        "resetpass_forbidden": "Paroley nêşikinê bıvurniyê",
        "resetpass-submit-loggedin": "Parola bıvurne",
-       "resetpass-submit-cancel": "Bıtexelne",
+       "resetpass-submit-cancel": "Peyd kı",
        "resetpass-temp-password": "Parola vêrdiye:",
        "bold_sample": "Nusto qolınd",
        "bold_tip": "Nusto qolınd",
index 688ee15..92b86c0 100644 (file)
        "rollbacklinkcount-morethan": "{{PLURAL:$1|편집}} $1회 이상 되돌리기",
        "rollbackfailed": "되돌리기 실패",
        "rollback-missingparam": "요청에 필요한 변수가 존재하지 않습니다.",
+       "rollback-missingrevision": "판 데이터를 불러올 수 없습니다.",
        "cantrollback": "편집을 되돌릴 수 없습니다.\n문서를 편집한 저자가 한 명뿐입니다.",
        "alreadyrolled": "[[:$1]]에서 [[User:$2|$2]] ([[User talk:$2|토론]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])의 편집을 되돌릴 수 없습니다.\n누군가가 이미 문서를 고치거나 되돌렸습니다.\n\n마지막으로 이 문서를 편집한 사용자는 [[User:$3|$3]] ([[User talk:$3|토론]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])입니다.",
        "editcomment": "편집 요약: <em>$1</em>",
index f9bb80c..510249a 100644 (file)
        "rollbacklinkcount-morethan": "méi wéi {{PLURAL:$1|Eng Ännerung|$1 Ännerungen}} zrécksetzen",
        "rollbackfailed": "Zrécksetzen huet net geklappt",
        "rollback-missingparam": "An der Ufro feelen obligatoresch Parameteren.",
+       "rollback-missingrevision": "D'Donnéeë vun der Versioun konnten net geluede ginn.",
        "cantrollback": "Lescht Ännerung kann net zréckgesat ginn. De leschten Auteur ass deen eenzegen Auteur vun dëser Säit.",
        "alreadyrolled": "Déi lescht Ännerung vun der Säit [[:$1]] vum [[User:$2|$2]] ([[User talk:$2|talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); kann net zréckgesat ginn;\neen Aneren huet dat entweder scho gemaach oder nei Ännerungen agedroen.\n\nDéi lescht Ännerung vun der Säit war vum [[User:$3|$3]] ([[User talk:$3|Diskussioun]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "De Resumé vun der Ännerung war: <em>$1</em>.",
        "anoncontribs": "Kontributiounen",
        "contribsub2": "Fir {{GENDER:$3|den $1|d'$1|de Benotzer $1}} ($2)",
        "contributions-userdoesnotexist": "De Benotzerkont \"$1\" ass net registréiert.",
-       "nocontribs": "Et goufe keng Ännerunge fonnt, déi dëse Kritèren entspriechen.",
+       "nocontribs": "Et goufe keng Ännerunge fonnt, déi dëse Critèren entspriechen.",
        "uctop": "(aktuell)",
        "month": "Vum Mount (a virdrun):",
        "year": "Vum Joer (a virdrun):",
        "credentialsform-account": "Numm vum Kont:",
        "cannotlink-no-provider-title": "Et gëtt keng Benotzerkonte fir ze verlinken",
        "linkaccounts": "Benotzerkonte verbannen",
-       "linkaccounts-submit": "Benotzerkonte verbannen"
+       "linkaccounts-submit": "Benotzerkonte verbannen",
+       "userjsispublic": "DEnkt drun: Op JavaScript-Ënnersäite solle keng vertraulech Informatioune stoe well se vun anere Benotzer kënne gesi ginn."
 }
index e02a91c..595fdf5 100644 (file)
        "sqlite-no-fts": "$1 बिन पूर्ण-पाठ खोज सहायताक",
        "logentry-delete-delete": "$1 पृष्ठ $3 {{GENDER:$2|मेटौलक}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
-       "logentry-delete-event": "$1 {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
-       "logentry-delete-revision": "$1 {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  पन्ना $3: $4 पर",
+       "logentry-delete-event": "$1 {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
+       "logentry-delete-revision": "$1 {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  पन्ना $3: $4 पर",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख दृश्य",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख संशोधन",
-       "logentry-suppress-delete": "$1 {{लिंग:$2|दबाएल}} page $3",
-       "logentry-suppress-event": "$1 चोरिसँ {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
-       "logentry-suppress-revision": "$1 चोरिसँ {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
+       "logentry-suppress-delete": "$1 {{GENDER:$2|दबाएल}} page $3",
+       "logentry-suppress-event": "$1 चोरिसँ {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
+       "logentry-suppress-revision": "$1 चोरिसँ {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
        "logentry-suppress-event-legacy": "$1 नुका क {{GENDER:$2|परिवर्तन}}  $3 पर वृत्तलेख दृश्य",
        "logentry-suppress-revision-legacy": "$1 नुका कऽ {{GENDER:$2|changed}}  $3 पर संशोधन दृश्य",
        "revdelete-content-hid": "सामिग्री नुकाएल",
        "logentry-move-move": "$1 हटाएल पन्ना $3 सँ $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआकेँ बिना छोड़ने",
        "logentry-move-move_redir": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतिरिक्त",
-       "logentry-move-move_redir-noredirect": "$1 {{लिंग:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित",
        "logentry-patrol-patrol-auto": "$1 स्वतः {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित",
        "logentry-newusers-newusers": "$1 {{GENDER:$2|बनाएल}} एकटा प्रयोक्ता खाता",
index 33ea41a..2e0455e 100644 (file)
        "rollbacklinkcount-morethan": "отповикај повеќе од $1 {{PLURAL:$1|уредување|уредувања}}",
        "rollbackfailed": "Отповикувањето не успеа",
        "rollback-missingparam": "Недостасуваат задолжителни параметри за барањето.",
+       "rollback-missingrevision": "Не можам да ги вчитам податоците за преработката.",
        "cantrollback": "Уредувањето не може да се отповика.\nПоследниот уредник е воедно и единствениот автор на страницата.",
        "alreadyrolled": "Не може да се отповика последното уредување на страницата „[[:$1]]“ извршено од  [[User:$2|$2]] ([[User talk:$2|разговор]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nнекој друг веќе ја изменил или отповикал страницата.\n\nПоследното уредување го изврши [[User:$3|$3]] ([[User talk:$3|разговор]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Коментарот на уредувањето беше: <em>$1</em>.",
index d8bf6e3..ba463cd 100644 (file)
        "rollbacklinkcount": "उलटवा $1 {{PLURAL:$1|संपादन|संपादने}}",
        "rollbacklinkcount-morethan": "$1 पेक्षा अधिक {{PLURAL:$1|संपादन|संपादने}} उलटवा",
        "rollbackfailed": "द्रूतमाघार फसली",
+       "rollback-missingrevision": "आवृत्ती डाटा भारण करु शकत नाही.",
        "cantrollback": "जुन्या आवृत्तीकडे परतवता येत नाही; शेवटचा संपादक या पानाचा एकमात्र लेखक आहे.",
        "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|Talk]] [[Special:Contributions/$2|{{int:contribslink}}]])चे शेवटाचे [[:$1]]वे संपादन माघारी परतवता येत नाही; पान आधीच कुणी माघारी परतवले आहे किंवा संपादित केले आहे.\n\nशेवटचे संपादन [[User:$3|$3]] ([[User talk:$3|Talk]] [[Special:Contributions/$3|{{int:contribslink}}]])-चे होते.",
        "editcomment": "संपादन सारांश <em>$1</em> होता.",
        "rollback-success": "$1 ने उलटवलेली संपादने;$2 च्या आवृत्तीस परत नेली.",
        "sessionfailure-title": "सत्र त्रुटी",
        "sessionfailure": "तुमच्या दाखल सत्रात काही समस्या दिसते;सत्र अपहारणापासून \nवाचविण्याचे दृष्टीने ही कृती रद्द केल्या गेली आहे.कृपया आपल्या विचरकाच्या \"back\" कळीवर टिचकी मारा आणि तुम्ही ज्या पानावरून आला ते पुन्हा चढवा,आणि परत प्रयत्न करा.",
+       "changecontentmodel": "पानाचा आशय नमूना (कंटेंट मॉडेल) बदला",
        "changecontentmodel-title-label": "लेखपान शीर्ष",
        "changecontentmodel-reason-label": "कारण:",
+       "changecontentmodel-submit": "बदला",
        "logentry-contentmodel-change-revertlink": "उलटवा",
        "logentry-contentmodel-change-revert": "उलटवा",
        "protectlogpage": "सुरक्षा नोंदी",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "कुकी-आधारीत सत्रे",
        "sessionprovider-nocookies": "कुकिज अक्षम असू शकतात. याची खात्री करा कि कुकिज सक्षम केल्या आहेत व पुन्हा सुरुवात करा.",
        "randomrootpage": "अविशिष्ट मूळ पान",
-       "log-action-filter-suppress-block": "रोधामार्फत सदस्य दाबणे"
+       "log-action-filter-suppress-block": "रोधामार्फत सदस्य दाबणे",
+       "changecredentials": "अधिकारपत्रे (क्रेडेंटियल्स)बदला",
+       "removecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) हटवा"
 }
index 581cc97..d7e8636 100644 (file)
        "expand_templates_generate_xml": "Vis parsetre som XML",
        "expand_templates_generate_rawhtml": "Vis ubehandlet HTML",
        "expand_templates_preview": "Forhåndsvisning",
-       "expand_templates_preview_fail_html": "<em>Fordi {{SITENAME}} har slått på rå HTML og sesjonsdata ble tapt er forhåndsvisningen skjult for å beskytte mot JavaScript-angrep.</em>\n\n<strong>Om dette er et legitimt forsøk på å forhåndsvise, prøv igjen.</strong> Om det fortsatt ikke fungerer, prøv å [[Special:UserLogout|logge ut]] og logge inn igjen.",
+       "expand_templates_preview_fail_html": "<em>Fordi {{SITENAME}} har slått på rå HTML og sesjonsdata ble tapt er forhåndsvisningen skjult for å beskytte mot JavaScript-angrep.</em>\n\n<strong>Om dette er et legitimt forsøk på å forhåndsvise, prøv på nytt.</strong> Om det fortsatt ikke fungerer, prøv å [[Special:UserLogout|logge ut]] og logge inn igjen, og sjekk at nettleseren din godtar nettkapsler fra dette nettstedet.",
        "expand_templates_preview_fail_html_anon": "<em>Fordi {{SITENAME}} har slått på rå HTML og du ikke er logget inn er forhåndsvisningen skjult for å beskytte mot JavaScript-angrep.</em>\n\n<strong>Om dette er et legitimt forsøk på å forhåndsvise, [[Special:UserLogin|logg inn]] og prøv igjen.</strong>",
        "pagelanguage": "Endre sidespråk",
        "pagelang-name": "Side",
        "mediastatistics": "Mediestatistikk",
        "mediastatistics-summary": "Statistikk over opplastede filtyper. Dette inkluderer bare den nyeste versjonen av hver fil. Eldre eller slettede versjoner av filene er eksludert.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte}} ($2; $3 %)",
-       "mediastatistics-bytespertype": "Total filstørrelse for denne seksjonen: $1 byte.",
-       "mediastatistics-allbytes": "Total filstørrelse for alle filer: $1 byte.",
+       "mediastatistics-bytespertype": "Total filstørrelse for denne seksjonen: {{PLURAL:$1|$1 byte}} ($2; $3 %).",
+       "mediastatistics-allbytes": "Total filstørrelse for alle filer: {{PLURAL:$1|$1 byte}} ($2).",
        "mediastatistics-table-mimetype": "MIME-type",
        "mediastatistics-table-extensions": "Mulige filtyper",
        "mediastatistics-table-count": "Antall filer",
index 4a97196..cd91aec 100644 (file)
        "ipb-edit-dropdown": "निषेध कारण सम्पादन गर्नुहोस्",
        "ipb-unblock-addr": "$1 निषेध खारेज गर्ने",
        "ipb-unblock": "प्रयोगकर्ता वा IP माथिको निषेध खारेज गर्ने",
-       "ipb-blocklist": "हाल à¤°à¤¹à¥\87à¤\95ा à¤¨à¤¿à¤·à¥\87धहरà¥\81 हेर्नुहोस्",
+       "ipb-blocklist": "हाल à¤°à¤¹à¥\87à¤\95ा à¤¨à¤¿à¤·à¥\87धहरà¥\82 हेर्नुहोस्",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}}को लागि योगदान",
        "unblockip": "प्रयोगकर्ताको निषेध खारेज गर्नुहोस्",
        "unblockiptext": "IP ठेगाना अथवा प्रयोगकर्तामाथि पहिले लगाइएको रोक फुकुवा गर्न तलको प्रपत्र प्रयोग गर्नुहोस्।",
        "revdelete-content-unhid": "सामग्री देखाइएको",
        "revdelete-summary-unhid": "सम्पादन सारांस देखाइएको",
        "revdelete-uname-unhid": "प्रयोगकर्ता देखाइएको",
-       "revdelete-restricted": "पà¥\8dरबनà¥\8dधà¤\95हरà¥\81माथि सीमितता लागू गरियो",
-       "revdelete-unrestricted": "प्रवन्धककोलागि निषेधहरु हटाइयो ।",
+       "revdelete-restricted": "पà¥\8dरबनà¥\8dधà¤\95हरà¥\82 माथि सीमितता लागू गरियो",
+       "revdelete-unrestricted": "प्रवन्धकको लागि निषेधहरू हटाइयो ।",
        "logentry-block-block": "$1 {{GENDER:$2|प्रतिबन्धित}}{{GENDER:$4|$3}} जसमा समय समाप्तिको अवधि छ $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|खुल्ला गरिएो}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|परिवर्तन गर्यो}} प्रतिबन्ध सेटिङ्ग {{GENDER:$4|$3}} को लागि जसमा समय समाप्तिको अवधि छ $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|द्वारा}} $3 पृष्ठलाई $4 मा सारियो",
        "logentry-move-move-noredirect": "$1 ले $3 मा पुनर्निर्देश नछोडि त्यसलाई $4 मा {{GENDER:$2|सारेको}} हो",
        "logentry-move-move_redir": "$1 ले $4 बाट पुनर्निर्देश हटाएर $3 लाई त्यसमाथि {{GENDER:$2|सारेको}} हो",
-       "logentry-move-move_redir-noredirect": "$1 à¤²à¥\87 $4 à¤¬à¤¾à¤\9f à¤ªà¥\81नारà¥\8dनिरà¥\8dदà¥\87श à¤¹à¤\9fाà¤\8fर $3 à¤®à¤¾ à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श à¤¨à¥\8dनाà¤\9bà¥\8bडि $3 लाई $4 मा {{GENDER:$2|सारेको}} हो",
+       "logentry-move-move_redir-noredirect": "$1 à¤²à¥\87 $4 à¤¬à¤¾à¤\9f à¤ªà¥\81नारà¥\8dनिरà¥\8dदà¥\87श à¤¹à¤\9fाà¤\8fर $3 à¤®à¤¾ à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श à¤¨à¤\9bà¥\8bडà¥\80 $3 लाई $4 मा {{GENDER:$2|सारेको}} हो",
        "logentry-patrol-patrol": "$1 ले $3 पृष्ठको $4 अवतरणलाई गस्ती गरिएको {{GENDER:$2|चिन्हित}} गरेको हो",
        "logentry-patrol-patrol-auto": "$1 ले $3 पृष्ठको $4 अवतरणलाई स्वचालित रूपले गस्ती गरिएको {{GENDER:$2|चिन्हित}} गरेको हो",
        "logentry-newusers-newusers": "प्रयोगकर्ता खाता $1 {{GENDER:$2|खोलियो}}",
index e329be0..c61a5c6 100644 (file)
        "viewsource": "Vejatz lo tèxte font",
        "viewsource-title": "Veire la font de $1",
        "actionthrottled": "Accion limitada",
-       "actionthrottledtext": "Per luchar contra lo spam, l’utilizacion d'aquesta accion es limitada a un cèrt nombre de còps dins una sosta pro corta. S'avèra qu'avètz depassat aqueste limit. Ensajatz tornamai dins qualques minutas.",
+       "actionthrottledtext": "Per lutar contra lo spam, l’utilizacion d'aquesta accion es limitada a un cèrt nombre de còps dins un periòde pro cort. S'avèra qu'avètz despassat aqueste limit. Ensajatz tornamai dins qualques minutas.",
        "protectedpagetext": "Aquesta pagina es estada protegida per empachar sa modificacion o d'autras accions.",
-       "viewsourcetext": "Podètz veire e copiar lo contengut de l’article per poder trabalhar dessús :",
-       "viewyourtext": "Podètz veire e copiar lo contengut de '''vòstras modificacions''' a aquesta pagina :",
+       "viewsourcetext": "Podètz veire e copiar lo contengut d'aquesta pagina.",
+       "viewyourtext": "Podètz veire e copiar lo contengut de <strong>vòstras modificacions</strong> a aquesta pagina.",
        "protectedinterface": "Aquesta pagina provesís de tèxte d’interfàcia pel logicial susaqueste wiki, e es protegida per evitar los abuses.\nPer apondre o modificar de traduccions sus totes los wikis, utilizatz [https://translatewiki.net/ translatewiki.net], lo projècte de localizacion de MediaWiki.",
        "editinginterface": "<strong>Atencion :<strong> sètz a mand de modificar una pagina utilizada per crear lo tèxte de l’interfàcia del logicial.\nLos cambiaments sus aquesta pagina se repercutaràn sus l'aparéncia de l'interfàcia d'utilizaire pels autres utilizaires d'aqueste wiki.",
        "cascadeprotected": "Aquesta pagina es actualament protegida perque es inclusa dins {{PLURAL:$1|la pagina seguenta|las paginas seguentas}}, {{PLURAL:$1|qu'es estada protegida|que son estadas protegidas}} amb l’opcion « proteccion en cascada » activada :\n$2",
        "newpassword": "Senhal novèl :",
        "retypenew": "Confirmar lo senhal novèl :",
        "resetpass_submit": "Cambiar lo senhal e s’enregistrar",
-       "changepassword-success": "Vòstre senhal es estat cambiat amb succès !",
+       "changepassword-success": "Vòstre senhal es estat modificat !",
        "changepassword-throttled": "Avètz ensajat un tròp grand nombre de connexions darrièrament.\nEsperatz $1 abans d’ensajar tornarmai.",
        "botpasswords": "Senhals de robòts",
        "resetpass_forbidden": "Los senhals pòdon pas èsser cambiats",
        "deletepage": "Suprimir la pagina",
        "confirm": "Confirmar",
        "excontent": "contenent '$1'",
-       "excontentauthor": "lo contengut èra : « $1 » (e l'unic contributor èra « [[Special:Contributions/$2|$2]] »)",
+       "excontentauthor": "conteniá « $1 » e son sol contributor èra «[[Special:Contributions/$2|$2]]» ([[User talk:$2|talk]])",
        "exbeforeblank": "lo contengut abans blanquiment èra :'$1'",
        "delete-confirm": "Escafar «$1»",
        "delete-legend": "Escafar",
        "undeletepagetext": "{{PLURAL:$1|Aquesta pagina es estada escafada e se tròba|Aquestas paginas son estadas escafadas e se tròban}} dins l'archiu. {{PLURAL:$1|Figura|Figuran}} encara dins la basa de donada e {{PLURAL:$1|pòt èsser restablida|pòdon èsser restablidas}}.\nL'archiu pòt èsser escafat periodicament.",
        "undelete-fieldset-title": "Restablir las versions",
        "undeleteextrahelp": "Per restablir l'istoric complet d'aquesta pagina, daissatz vèrjas totas las casas de marcar, puèi clicatz sus '''''Restablir'''''.\nPer efectuar un restabliment parcial, marcatz las casas que correspondon a las versions que son de restablir, puèi clicatz sus '''''Restablir'''''.",
-       "undeleterevisions": "$1 {{PLURAL:$1|revision archivada|revisions archivadas}}",
+       "undeleterevisions": "{{PLURAL:$1|Una revision suprimida|$1 revisions suprimidas}}",
        "undeletehistory": "Se restablissètz la pagina, totas las revisions seràn plaçadas tornamai dins l'istoric.\n\nS'una pagina novèla amb lo meteis nom es estada creada dempuèi la supression, las revisions restablidas apareisseràn dins l'istoric anterior e la version correnta serà pas automaticament remplaçada.",
        "undeleterevdel": "Lo restabliment serà pas efectuat se, fin finala, la version mai recenta de la pagina es parcialament suprimida. Dins aqueste cas, vos cal deseleccionatz las versions mai recentas (en naut). Las versions dels fichièrs a las qualas avètz pas accès seràn pas restablidas.",
        "undeletehistorynoadmin": "Aqueste article es estat suprimit. Lo motiu de la supression es indicat dins lo resumit çaijós, amb los detalhs dels utilizaires que l’an modificat abans sa supression. Lo contengut d'aquestas versions es pas accessible qu’als administrators.",
        "sp-contributions-newbies-sub": "Lista de las contribucions dels utilizaires novèls. Las paginas que son estadas suprimidas son pas afichadas.",
        "sp-contributions-newbies-title": "Las contribucions de l’utilizaire pels comptes novèls",
        "sp-contributions-blocklog": "Istoric dels blocatges",
-       "sp-contributions-suppresslog": "contribucions suprimidas d’un utilizaire",
-       "sp-contributions-deleted": "contribucions suprimidas",
+       "sp-contributions-suppresslog": "contribucions de l'{{GENDER:$1|utilizaire|utilizaira}} suprimidas",
+       "sp-contributions-deleted": "contribucions de l'{{GENDER:$1|utilizaire|utilizaira}} suprimidas",
        "sp-contributions-uploads": "impòrts",
        "sp-contributions-logs": "jornals",
        "sp-contributions-talk": "Discutir",
        "whatlinkshere-hideredirs": "$1 las redireccions",
        "whatlinkshere-hidetrans": "$1 las inclusions",
        "whatlinkshere-hidelinks": "$1 ligams",
-       "whatlinkshere-hideimages": "$1 los fichièrs ligats",
+       "whatlinkshere-hideimages": "$1 los ligams cap al fichièr",
        "whatlinkshere-filters": "Filtres",
        "autoblockid": "Blocatge automatic #$1",
        "block": "Blocar un utilizaire",
index fe587b1..48f846a 100644 (file)
        "title-invalid-too-long": "Podany tytuł strony jest zbyt długi. Nie może mieć więcej niż $1 {{PLURAL:$1|bajt|bajty|bajtów}} w kodowaniu UTF-8.",
        "title-invalid-leading-colon": "Podany tytuł strony zawiera na początku nieprawidłowy dwukropek.",
        "perfcached": "Poniższe dane są kopią z pamięci podręcznej i mogą być nieaktualne. W pamięci podręcznej {{PLURAL:$1|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$1|jeden wynik|$1 wyniki|$1 wyników}}.",
-       "perfcachedts": "Poniższe dane są kopią z pamięci podręcznej. Ostatnia aktualizacja odbyła się $1. W pamięci podręcznej {{PLURAL:$4|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$4|jeden wynik|$4 wyniki|$4 wyników}}.",
+       "perfcachedts": "Poniższe dane są kopią z pamięci podręcznej. Ostatnia aktualizacja odbyła się $1. W pamięci podręcznej {{PLURAL:$4|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$4|jeden wynik|$4 wyniki|$4 wyników}}.",
        "querypage-no-updates": "Uaktualnienia dla tej strony są obecnie wyłączone. Znajdujące się tutaj dane nie zostaną odświeżone.",
        "viewsource": "Tekst źródłowy",
        "viewsource-title": "Tekst źródłowy strony $1",
        "authpage-cannot-create-continue": "Nie można kontynuować tworzenia konta. Twoja sesja najprawdopodobniej wygasła.",
        "cannotauth-not-allowed-title": "Brak dostępu",
        "cannotauth-not-allowed": "Nie masz uprawnień, aby skorzystać z tej strony",
-       "changecredentials-submit": "Zmień poświadczenia",
-       "removecredentials-submit": "Usuń poświadczenia",
+       "changecredentials": "Zmiana poświadczeń",
+       "changecredentials-submit": "Zmień poświadczenie",
+       "removecredentials": "Usuwanie poświadczeń",
+       "removecredentials-submit": "Usuń poświadczenie",
+       "credentialsform-provider": "Rodzaj poświadczeń:",
        "credentialsform-account": "Nazwa konta:",
        "linkaccounts": "Połącz konta",
        "linkaccounts-success-text": "Konto zostało połączone.",
index 2c5041c..48f2013 100644 (file)
        "rollbacklinkcount-morethan": "{{doc-actionlink}}\nText of the rollback link when a greater number of edits is to be rolled back. See also {{msg-mw|rollbacklink}}.\n\nWhen the number of edits rolled back is smaller than [[mw:Special:MyLanguage/Manual:$wgShowRollbackEditCount|$wgShowRollbackEditCount]], {{msg-mw|rollbacklinkcount}} is used instead.\n\nParameters:\n* $1 - number of edits",
        "rollbackfailed": "{{Identical|Rollback}}",
        "rollback-missingparam": "Used as error message that rollback is accessed without the required parameters\n\nSee also:\n* {{msg-mw|Rollbackfailed}}",
+       "rollback-missingrevision": "Used as error message that rollback failed to load revision data\n\nSee also:\n* {{msg-mw|Rollbackfailed}}",
        "cantrollback": "Used as error message when rollback fails due to there not being a valid revision to revert back to.\n\nSee also:\n* {{msg-mw|Notvisiblerev}}\n{{Identical|Revert}}\n{{Identical|Rollback}}",
        "alreadyrolled": "Appear when there's rollback and/or edit collision.\n\nRefers to:\n* {{msg-mw|Pipe-separator}}\n* {{msg-mw|Contribslink}}\nParameters:\n* $1 - the page to be rolled back\n* $2 - the editor to be rolled-back of that page\n* $3 - the editor that cause collision\n{{Identical|Rollback}}",
        "editcomment": "Only shown if there is an edit {{msg-mw|Summary}}. Parameters:\n* $1 - the edit summary",
index 953be9c..810c6c5 100644 (file)
        "title-invalid-characters": "Запрашиваемое название страницы содержит недопустимые символы: «$1».",
        "title-invalid-relative": "Заголовок имеет относительный путь. Заголовки страниц с относительным путем (/,../) являются недействительными, так как они часто недоступны, когда обрабатываются браузером пользователя.",
        "title-invalid-magic-tilde": "Запрашиваемый заголовок страницы содержит недопустимую последовательность тильды (<nowiki>~~~</nowiki>).",
-       "title-invalid-too-long": "Запрашиваемый заголовок страницы слишком длинен. Он должен быть не более $1 {{PLURAL:$1|байта|байтов}} в кодировке UTF-8.",
+       "title-invalid-too-long": "Запрашиваемый заголовок страницы слишком длинен. Он должен быть не более $1 {{PLURAL:$1|байта|байт}} в кодировке UTF-8.",
        "title-invalid-leading-colon": "Запрашиваемое название страницы содержит недопустимое двоеточие в начале.",
        "perfcached": "Следующие данные взяты из кэша и могут не учитывать последних изменений. В кэше хранится не более $1 {{PLURAL:$1|записи|записей}}.",
        "perfcachedts": "Следующие данные взяты из кэша, последний раз он обновлялся в $1. В кэше хранится не более $4 {{PLURAL:$4|записи|записей}}.",
        "prefs-watchlist-token": "Токен списка наблюдения:",
        "prefs-misc": "Другие настройки",
        "prefs-resetpass": "Изменить пароль",
-       "prefs-changeemail": "Ð\98зменить или удалить адрес электронной почты",
+       "prefs-changeemail": "изменить или удалить адрес электронной почты",
        "prefs-setemail": "Установка адреса эл. почты",
        "prefs-email": "Параметры электронной почты",
        "prefs-rendering": "Внешний вид",
        "withoutinterwiki-legend": "Префикс",
        "withoutinterwiki-submit": "Показать",
        "fewestrevisions": "Страницы с наименьшим количеством версий",
-       "nbytes": "$1 {{PLURAL:$1|байт|байта|байтов}}",
+       "nbytes": "$1 {{PLURAL:$1|байт|байта|байт}}",
        "ncategories": "$1 {{PLURAL:$1|категория|категории|категорий}}",
        "ninterwikis": "$1 {{PLURAL:$1|интервики-ссылка|интервики-ссылки|интервики-ссылок}}",
        "nlinks": "$1 {{PLURAL:$1|ссылка|ссылки|ссылок}}",
        "rollbacklinkcount-morethan": "откатить больше, чем $1 {{PLURAL:$1|правку|правки|правок}}",
        "rollbackfailed": "Ошибка при совершении отката",
        "rollback-missingparam": "Отсутствуют обязательные параметры по запросу.",
+       "rollback-missingrevision": "Не удалось загрузить данные версии.",
        "cantrollback": "Невозможно откатить изменения. Последним, кто вносил изменения, был единственный автор этой страницы.",
        "alreadyrolled": "Невозможно откатить последние изменения страницы «[[:$1]]», совершённые [[User:$2|$2]] ([[User talk:$2|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]),\nпоскольку кто-то другой уже успел откатить эти правки или отредактировать страницу.\n\nПоследние изменения {{GENDER:$3|внёс|внесла}} [[User:$3|$3]] ([[User talk:$3|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Было дано описание изменения: <em>$1</em>.",
        "limitreport-ppvisitednodes": "Количество узлов, посещённых препроцессором",
        "limitreport-ppgeneratednodes": "Количество сгенерированных препроцессором узлов",
        "limitreport-postexpandincludesize": "Размер раскрытых включений",
-       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|байт|байта|байтов}}",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|байт|байта|байт}}",
        "limitreport-templateargumentsize": "Размер аргумента шаблона",
-       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|байт|байта|байтов}}",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|байт|байта|байт}}",
        "limitreport-expansiondepth": "Наибольшая глубина расширения",
        "limitreport-expensivefunctioncount": "Количество «дорогих» функций анализатора",
        "expandtemplates": "Развёртка шаблонов",
        "linkaccounts-submit": "Связать учётные записи",
        "unlinkaccounts": "Отвязать учётные записи",
        "unlinkaccounts-success": "Учетная запись была отвязан.",
-       "authenticationdatachange-ignored": "Изменение данных для проверки подлинности не было обработано. Может быть, не был настроен ни один провайдер?"
+       "authenticationdatachange-ignored": "Изменение данных для проверки подлинности не было обработано. Может быть, не был настроен ни один провайдер?",
+       "userjsispublic": "Обратите внимание: подстраницы JavaScript не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам.",
+       "usercssispublic": "Обратите внимание: подстраницы CSS не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам."
 }
index f1fad3c..f9cf164 100644 (file)
        "rollbacklinkcount-morethan": "vrni več kot $1 {{PLURAL:$1|urejanje|urejanji|urejanja|urejanj}}",
        "rollbackfailed": "Vrnitev ni uspela",
        "rollback-missingparam": "Pri zahtevi manjkajo zahtevani parametri.",
+       "rollback-missingrevision": "Ne moremo naložiti podatkov o redakciji.",
        "cantrollback": "Urejanja ne morem vrniti; zadnji urejevalec je hkrati edini.",
        "alreadyrolled": "Zadnje spremembe [[:$1]] uporabnika [[User:$2|$2]] ([[User talk:$2|pogovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ne morem vrniti;\nstran je spremenil ali vrnil že nekdo drug.\n\nZadnji je stran urejal uporabnik [[User:$3|$3]] ([[User talk:$3|pogovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Povzetek urejanja je bil: <em>$1</em>.",
index 33c3522..c23dca5 100644 (file)
        "rollbacklinkcount-morethan": "rulla tillbaka mer än $1 {{PLURAL:$1|redigering|redigeringar}}",
        "rollbackfailed": "Tillbakarullning misslyckades",
        "rollback-missingparam": "Nödvändiga parametrar i begäran saknas.",
+       "rollback-missingrevision": "Kunde inte läsa in sidversionsdata.",
        "cantrollback": "Det gick inte att rulla tillbaka, då sidan endast redigerats av en användare.",
        "alreadyrolled": "Det gick inte att rulla tillbaka den senaste redigeringen av [[User:$2|$2]] ([[User talk:$2|diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) på sidan [[:$1|$1]]. Någon annan har redan rullat tillbaka eller redigerat sidan.\n\nSidan ändrades senast av [[User:$3|$3]] ([[User talk:$3|diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]).",
        "editcomment": "Redigeringskommentaren var: <em>$1</em>.",
        "whatlinkshere": "Vad som länkar hit",
        "whatlinkshere-title": "Sidor som länkar till \"$1\"",
        "whatlinkshere-page": "Sida:",
-       "linkshere": "Följande sidor länkar till '''[[:$1]]''':",
+       "linkshere": "Följande sidor länkar till <strong>[[:$1]]</strong>:",
        "nolinkshere": "Inga sidor länkar till '''[[:$1]]'''.",
        "nolinkshere-ns": "Inga sidor i den angivna namnrymden länkar till '''[[:$1]]'''.",
        "isredirect": "omdirigeringssida",
index f80b4cd..b1bb11e 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|புதிய பக்கங்கள் பட்டியலையும்]] காணவும்)",
        "recentchanges-submit": "காட்டு",
        "rcnotefrom": "கீழே காணப்படுவது <strong>$3, $4</strong> இலிருந்து செய்யப்பட்ட (<strong>$1</strong> வரைக் காட்டப்பட்டுள்ளது) {{PLURAL:$5|மாற்றமாகும்.|மாற்றங்களாகும்.}}",
-       "rclistfrom": "$2, $3 à®¤à¯\8aà®\9fà®\95à¯\8dà®\95à®®à¯\8d செய்யப்பட்ட புதிய மாற்றங்களைக் காட்டவும்",
+       "rclistfrom": "$2, $3 à®®à¯\81தலà¯\8d à®\87னà¯\8dà®±à¯\81 à®µà®°à¯\88 செய்யப்பட்ட புதிய மாற்றங்களைக் காட்டவும்",
        "rcshowhideminor": "சிறிய தொகுப்புகளை $1",
        "rcshowhideminor-show": "காட்டு",
        "rcshowhideminor-hide": "மறை",
index d9a5592..ee6bff0 100644 (file)
@@ -9,7 +9,8 @@
                        "Bharathesha Alasandemajalu",
                        "Soundarya shetty s",
                        "రహ్మానుద్దీన్",
-                       "BHARATHESHA ALASANDEMAJALU"
+                       "BHARATHESHA ALASANDEMAJALU",
+                       "Lokesha kunchadka"
                ]
        },
        "tog-underline": "ಲಿಂಕ್’ಲೆದ ತಿರ್ತ್ ಗೆರೆ(ಅಂಡರ್ ಲೈನ್) ಪಾಡ್’ಲೆ",
        "noname": "ಈರ್ ಸರಿಯಾಯಿನ ಬಳಕೆದಾರ ಪುದರ್ ಕೊರ್ತಿಜ್ಜರ್.",
        "loginsuccesstitle": "ಲಾಗ್ ಇನ್ ಯಶಸ್ವಿಯಾತ್ಂಡ್",
        "loginsuccess": "ಲಾಗ್ ಇನ್ ಯಶಸ್ವಿಯಾತ್‘ಂಡ್\". {{SITENAME}}  \"$1\".'''",
-       "nosuchuser": "!!\"$1\"ಪà³\81ದರà³\8dâ\80\98ದ à²µà²¾ à²¸à²¦à²¸à³\8dಯà³\86ರà³\8dâ\80\98ಲಾ à²\87à²\9cà³\8dà²\9cà³\86ರà³\8d, à²\85à²\95à³\8dಷರ à²¸à²°à²¿à²¯à²¾à²¦ ತೂಲೆ ಅಥವಾ  [[Special:CreateAccount|ಪೊಸ ಸದಸ್ಯತ್ವ  ಖಾತೆನ್ ಸೃಷ್ಟಿ ಮಲ್ಪುಲೆ]].",
+       "nosuchuser": "!!\"$1\"ಪà³\81ದರà³\8dâ\80\98ದ à²µà²¾ à²¸à²¦à²¸à³\8dಯà³\86ರà³\8dâ\80\98ಲಾ à²\87à²\9cà³\8dà²\9cà³\86ರà³\8d, à²\85à²\95à³\8dಷರ à²¸à²°à²¿à²¯à²¾à²¤à³\8d ತೂಲೆ ಅಥವಾ  [[Special:CreateAccount|ಪೊಸ ಸದಸ್ಯತ್ವ  ಖಾತೆನ್ ಸೃಷ್ಟಿ ಮಲ್ಪುಲೆ]].",
        "nosuchusershort": "!!\"$1\"ಪುದರ್‘ದ ವಾ ಸದಸ್ಯೆರ್‘ಲಾ ಇಜ್ಜೆರ್, ಅಕ್ಷರ ಸರಿಯಾದ ತೂಲೆ.",
        "nouserspecified": "ಈರ್ ಒಂಜಿ ಸದಸ್ಯತ್ವದ ಪುದರ್ ಸೂಚನೆ ಮಲ್ಪೊಡು.",
        "login-userblocked": "ಈ ಸದಸ್ಯರೆನ ಖಾತೆನ್ ತಡೆ ಪತ್ತ್‘ದುಂಡು. ಲಾಗ್ ಇನ್ ಮಲ್ಪರೆ ಆಪುಜ್ಜಿ.",
        "permissionserrors": "ಅನುಮತಿ ದೋಷ",
        "permissionserrorstext-withaction": "$2 ಗ್ ಇರೆಗ್ ಅನುಮತಿ ಇದ್ದಿ, ಅಯಿಕ್ {{PLURAL:$1|ಕಾರಣೊ|ಕಾರಣೊಲು}}:",
        "moveddeleted-notice": "ಈ ಪುಟೊ ಅಸ್ತಿತ್ವೊಡ್ ಇದ್ದಿ.\nಪುಟೊದ ಡಿಲೀಶನ್ ಅತ್ತ್ಂಡ್ ಕಡಪ್ಪುಡುನೆ ಲಾಗ್‍ನ್ ತೂಯರೆ ತಿರ್ತ್ ಕೊರ್ತ್ಂಡ್.",
+       "postedit-confirmation-saved": "ಇರೇನಾ ಸಂಪಾದನೆನ್ ಒರಿಪಾತುಂಡು.",
+       "edit-already-exists": "ಪೊಸ ಪುಟೋನು ಉಂಡು ಮಲ್ಪರೆ ಅಯಿಜಿ. ಅವ್ವು ದುಂಬೇ ಉಂಡು.",
        "content-model-wikitext": "ವಿಕಿ ಪಠ್ಯ",
        "viewpagelogs": "ಈ ಪುಟೊತ ದಾಕಲೆಲೆನ್ ತೂಲೆ",
        "nohistory": "ಈ ಪುಟಕ್ ಬದಲಾವಣೆದ ಇತಿಹಾಸ ಇಜ್ಜಿ",
        "page_last": "ಕಡೆತ",
        "history-fieldset-title": "ಇತಿಹಾಸಡ್ ನಾಡ್ಲೆ",
        "history-show-deleted": "ದೆತ್ತ್ ಪಾಡಿನ",
-       "histfirst": "ಬಾರಿ à²¦à³\81à²\82ಬà³\81ದ",
+       "histfirst": "ಪರ",
        "histlast": "ಪೊಸ",
        "historysize": "({{PLURAL:$1|೧ ಬೈಟ್|$1 ಬೈಟ್‍ಲು}})",
        "historyempty": "(ಖಾಲಿ)",
        "rev-showdeleted": "ತೊಜಾವು",
        "revisiondelete": "ಮಾಜಾಯಿನ/ಮಾಜಾವಂದಿನ ಬದಲಾವಣೆಲು",
        "revdelete-show-file-submit": "ಅಂದ್",
-       "revdelete-hide-text": "ಬದಲಾವಣà³\86ದ à²ªà² à³\8dಯನà³\8d à²¦à³\86à²\82à²\97ಾಲà³\86",
+       "revdelete-hide-text": "ಪರಿಷà³\8dà²\95ರಣà³\86 à²\86ಯಿನ à²ªà² à³\8dಯ",
        "revdelete-hide-image": "ಪೈಲ್‘ಡ್  ಇಪ್ಪುನ ಮಾಹಿತ್‘ನ್ ದೆಂಗಾಲೆ",
        "revdelete-hide-name": "ಕಾರ್ಯ ಬೊಕ್ಕ ಗುರಿನ್ ದೆಂಗಾಲ",
-       "revdelete-hide-comment": "ಸà²\82ಪಾದನà³\86ದ à²µà²¿à²µà²°à²£à³\86 à²¦à³\86à²\82à²\97ಾಲೆ",
-       "revdelete-radio-set": "à²\85à²\82ದà³\8d",
-       "revdelete-radio-unset": "à²\87à²\9cà³\8dà²\9cಿ",
+       "revdelete-hide-comment": "ಸಾರಾà²\82ಶ à²¸à²\82ಪà³\8aಲಿಪà³\81ಲೆ",
+       "revdelete-radio-set": "ದà³\86à²\82à²\97ಾಲà³\86",
+       "revdelete-radio-unset": "ತà³\8bà²\9cà³\81à²\82ಡà³\81",
        "revdelete-log": "ಕಾರಣ",
        "revdel-restore": "ವಿಸಿಬಿಲಿಟಿನ್ ಬದಲ್ ಮಲ್ಪುಲೆ",
        "pagehist": "ಪುಟೊತ ಚರಿತ್ರೆ",
        "action-read": "ಈ ಪುಟೊನು ಓದುಲೆ",
        "action-edit": "ಈ ಪುಟೊನು ಎಡಿಟ್ ಮಲ್ಪುಲೆ",
        "action-createpage": "ಈ ಪುಟೊನು ಸೃಷ್ಟಿಸಾಲೆ",
-       "action-createtalk": "ಚರ್ಚಾಪುಟೊಕ್‘ಲೆನ್ ಸೃಷ್ಟಿಸಾಲೆ",
+       "action-createtalk": "ಚರ್ಚಾ ಪುಟೊನ್ ಸೃಷ್ಟಿಸಾಲೆ",
        "action-createaccount": "ಈ ಸದಸ್ಯೆರನ ಖಾತೆನ್ ಸೃಷ್ಟಿ ಮಲ್ಪುಲೆ",
        "action-minoredit": "ಉದೊಂಜಿ ಎಲ್ಯ  ಬದಲಾವಣೆ",
        "action-move": "ಈ ಪೂಟೊನು ಮೂವ್(ಸ್ಥಳಾಂತರ) ಮಲ್ಪುಲೆ",
        "rc_categories_any": "ಒವ್ವೇ",
        "rc-change-size-new": "$1 {{PLURAL:$1|ಬೈಟ್|ಬೈಟ್‍ಲು}}ಬದಲಾವಣೆಡ್ದ್ ಬುಕ್ಕೊ",
        "newsectionsummary": "\n/* $1 */ಪೊಸ ವಿಭಾಗ",
-       "rc-enhanced-expand": "ವಿವರà³\8aಲà³\86ನà³\8d à²¤à³\8aà²\9cà³\8dಪಾವà³\81 (à²\9cಾವ à²¸à³\8dà²\95à³\8dರಿಪà³\8dà²\9fà³\8d à²¬à³\8bಡಾಪà³\81à²\82ಡà³\81)",
+       "rc-enhanced-expand": "ವಿವರà³\8aಲà³\86ನà³\8d à²¤à³\8aà²\9cಾವà³\8d",
        "rc-enhanced-hide": "ವಿವರೊಲೆನ್ ದೆಂಗಾವು",
        "recentchangeslinked": "ಸಂಬಂದೊ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
        "recentchangeslinked-feed": "ಸಂಬಂಧ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
        "imagelinks": "ಫೈಲ್‍ದ ಬಳಕೆ",
        "linkstoimage": "ಈ ತಿರ್ತ್‍ದ {{PLURAL:$1|ಪುಟ|$1 ಪುಟೊಲೆ ಕೊಂಡಿ}}ಈ ಫೈಲ್‍ಗ್ ಕೊರ್ಪುಂಡು.",
        "nolinkstoimage": "ಈ ಫೈಲ್‍ಗ್ ಸಂಪರ್ಕೊ ಉಪ್ಪುನ ವಾ ಪುಟೊಲಾ ಇದ್ದಿ.",
-       "sharedupload": "à²\88 à²«à³\88ಲà³\8dâ\80\99ನà³\8d à²®à²¸à³\8dತà³\8d à²\9cನ à²ªà²\9fà³\8dà²\9fà³\8dâ\80\99ದà³\81ಲà³\8dಲà³\86ರà³\8d à²\85à²\82à²\9aà³\86ನà³\86 à²\89à²\82ದà³\81 à²®à²¸à³\8dತà³\8d à²ªà³\8dರà³\8aà²\9cà³\86à²\95à³\8dà²\9fà³\8dâ\80\99ಲà³\86ಡà³\8d à²\89ಪಯà³\8bà²\97ಡà³\81ಪà³\8dಪà³\81.",
+       "sharedupload": "à²\88 à²«à³\88ಲà³\8dâ\80\99ನà³\8d à²®à²¸à³\8dತà³\8d à²\9cನ à²ªà²\9fà³\8dà²\9fà³\8dâ\80\99ದà³\81ಲà³\8dಲà³\86ರà³\8d à²\85à²\82à²\9aà³\86ನà³\86 à²\89à²\82ದà³\81 à²®à²¸à³\8dತà³\8d à²ªà³\8dರà³\8aà²\9cà³\86à²\95à³\8dà²\9fà³\8dâ\80\99ಲà³\86ಡà³\8d à²\89ಪಯà³\8bà²\97ಿಸà³\8aಲಿ",
        "sharedupload-desc-here": "ಈ ಪುಟೊ $1ಡ್ದ್ ಬೊಕ್ಕ ಬೇತೆ ಯೋಜನೆಡ್ದ್ ಗಳಸೊಲಿ.\nಈ ಪುಟೊತ ವಿವರೊ [$2 ಪುಟೊತ ವಿವರೊ] ತಿರ್ತ ಸಾಲ್‍ಡ್ ತೋಜಾದ್ಂಡ್",
        "upload-disallowed-here": "ಈರ್ ಈ ಫೈಲ್‍ನ್ ಕುಡೊರೊ ಬರೆವರೆ ಸಾದ್ಯೊ ಇದ್ದಿ.",
        "filerevert-comment": "ಕಾರಣ:",
index 4377326..7f2f2ea 100644 (file)
        "log-title-wildcard": "ఈ పాఠ్యంతో మొదలయ్యే పుస్తకాల కొరకు వెతుకు",
        "showhideselectedlogentries": "ఎంచుకున్న చిట్టా పద్దులను చూపించు/దాచు",
        "log-edit-tags": "ఎంచుకున్న చిట్టా ప్రవేశాల ట్యాగులను సవరించు",
+       "checkbox-all": "అన్నీ",
+       "checkbox-none": "దేన్నీ వద్దు",
+       "checkbox-invert": "తిరగవెయ్యి",
        "allpages": "అన్ని పేజీలు",
        "nextpage": "తరువాతి పేజీ ($1)",
        "prevpage": "మునుపటి పేజీ ($1)",
        "activeusers-hidebots": "బాట్లను దాచు",
        "activeusers-hidesysops": "నిర్వాహకులను దాచు",
        "activeusers-noresult": "వాడుకరులెవరూ లేరు.",
+       "activeusers-submit": "చేతనంగా ఉన్న వాడుకరులను చూపించు",
        "listgrouprights": "వాడుకరి గుంపుల హక్కులు",
        "listgrouprights-summary": "కింది జాబితాలో ఈ వికీలో నిర్వచించిన వాడుకరి గుంపులు, వాటికి సంబంధించిన హక్కులు ఉన్నాయి.\nవిడివిడిగా హక్కులకు సంబంధించిన మరింత సమాచారం [[{{MediaWiki:Listgrouprights-helppage}}]] వద్ద లభించవచ్చు.",
        "listgrouprights-key": "సూచిక:\n* <span class=\"listgrouprights-granted\">ప్రసాదించిన హక్కు</span>\n* <span class=\"listgrouprights-revoked\">వెనక్కి తీసుకున్న హక్కు</span>",
        "listgrouprights-namespaceprotection-header": "పేరుబరి నిబంధనలు",
        "listgrouprights-namespaceprotection-namespace": "పేరుబరి",
        "listgrouprights-namespaceprotection-restrictedto": "వాడుకరి మార్పు చేయుటకు హక్కు(లు)",
+       "listgrants": "గ్రాంట్లు",
+       "listgrants-grant": "గ్రాంటు",
+       "listgrants-rights": "హక్కులు",
        "trackingcategories": "పహారా కాయు వర్గాలు",
        "trackingcategories-msg": "పహారా కార్యు వర్గము",
        "trackingcategories-name": "సందేశం పేరు",
        "movepagetext-noredirectfixer": "కింది ఫారాన్ని వాడి, ఓ పేజీ పేరు మార్చవచ్చు. దాని చరిత్ర పూర్తిగా కొత్త పేరుకు తరలిపోతుంది. \nపాత శీర్షిక కొత్తదానికి దారిమార్పు పేజీగా మారిపోతుంది.\n[[Special:DoubleRedirects|double]] లేదా [[Special:BrokenRedirects|broken redirects]] లను చూడటం మరువకండి.\nలింకులు వెళ్ళాల్సిన చోటికి వెళ్తున్నాయని నిర్ధారించుకోవాల్సిన బాధ్యత మీదే.\nకొత్త పేరుతో ఈసరికే ఏదైనా పేజీ ఉంటే - అది ఖాళీగా ఉన్నా లేక మార్పుచేర్పుల చరిత్ర ఏమీ లేని దారిమార్పు పేజీ అయినా తప్ప- తరలింపు ’’’జరుగదు’’’ అని గమనించండి.\nఅంటే, ఏదైనా పొరపాటు జరిగితే పేరును తిరిగి పాత పేరుకే మార్చగలరు తప్ప, ఈపాటికే ఉన్న పేజీపై ఓవరరైటు చెయ్యలేరు.\n\n'''హెచ్చరిక!'''\nబహుళ వ్యాప్తి పొందిన ఓ పేజీలో ఈ మార్పు చాలా తీవ్రమైనది, ఊహించనిదీ అవుతుంది.\nదాని పర్యవసానాలు అర్థం చేసుకున్నాకే ముందుకు వెళ్ళండి.",
        "movepagetalktext": "దానితో పాటు సంబంధిత చర్చా పేజీ కూడా ఆటోమాటిక్‌‌గా తరలించబడుతుంది, '''కింది సందర్భాలలో తప్ప:'''\n*ఒక నేంస్పేసు నుండి ఇంకోదానికి తరలించేటపుడు,\n*కొత్త పేరుతో ఇప్పటికే ఒక చర్చా పేజీ ఉంటే,\n*కింది చెక్‌బాక్సులో టిక్కు పెట్టకపోతే.\n\nఆ సందర్భాలలో, మీరు చర్చా పేజీని కూడా పనిగట్టుకుని తరలించవలసి ఉంటుంది, లేదా ఏకీకృత పరచవలసి ఉంటుంది.",
        "moveuserpage-warning": "'''హెచ్చరిక:''' మీరు ఒక వాడుకరి పేజీని తరలించబోతున్నారు. పేజీ మాత్రమే తరలించబడుతుందనీ, వాడుకరి పేరుమార్పు జరగదనీ గమనించండి.",
+       "movecategorypage-warning": "<strong>హెచ్చరిక:</strong> మీరు ఓ వర్గం పేజీని తరలించబోతున్నారు. కేవలం పేజీ మాత్రమే తరలుతుందని, పాత వర్గంలో ఉన్న పేజీలేవీ కొత్త వర్గంలోకి <em>చేరవని</em>  గ్రహించండి.",
        "movenologintext": "పేజీని తరలించడానికి మీరు [[Special:UserLogin|లాగిన్‌]] అయిఉండాలి.",
        "movenotallowed": "పేజీలను తరలించడానికి మీకు అనుమతి లేదు.",
        "movenotallowedfile": "మీకు ఫైళ్ళను తరలించే అనుమతి లేదు.",
index 464655a..656ea39 100644 (file)
@@ -25,7 +25,8 @@
                        "Macofe",
                        "Pilarbini",
                        "Matma Rex",
-                       "B20180"
+                       "B20180",
+                       "Pon44695"
                ]
        },
        "tog-underline": "การขีดเส้นใต้ลิงก์:",
        "whatlinkshere-prev": "{{PLURAL:$1|ก่อนหน้า|ก่อนหน้า $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ถัดไป|ถัดไป $1}}",
        "whatlinkshere-links": "← ลิงก์",
-       "whatlinkshere-hideredirs": "$1การเปลี่ยนทาง",
+       "whatlinkshere-hideredirs": "$1 การเปลี่ยนทาง",
        "whatlinkshere-hidetrans": "$1 ถูกรวมอยู่",
        "whatlinkshere-hidelinks": "$1 ลิงก์",
        "whatlinkshere-hideimages": "$1ลิงก์ไฟล์",
index 66e7a0e..2c5bf98 100644 (file)
        "print": "Yazdır",
        "view": "Görüntüle",
        "view-foreign": "$1 üzerinde gör",
-       "edit": "Düzenle",
+       "edit": "Değiştir",
        "edit-local": "Yerel açıklamayı düzenle",
        "create": "Oluştur",
        "create-local": "Yerel açıklama ekle",
index ea5f273..5be33fa 100644 (file)
        "htmlform-no": "نہیں",
        "htmlform-yes": "ہاں",
        "logentry-delete-delete": "$1 {{GENDER:$2|حذف کیا گیا}} صفحہ $3",
-       "logentry-move-move": "$1 نے صفحہ $3 کو بجانب $4 منتقل کیا",
+       "logentry-move-move": "$1 نے صفحہ $3 کو $4 کی جانب منتقل کیا",
        "logentry-newusers-create": "صارف کھاتہ $1 {{GENDER:$2|بنایا گیا}}",
        "logentry-protect-move_prot": "$1 نے ترتیب درجہ حفاظت $4 سے $3 کی طرف {{GENDER:$2|منتقل کی}}",
        "logentry-protect-modify": "$1 نے $3 کا درجۂ حفاظت {{GENDER:$2|تبدیل کیا}} $4",
index 3076786..b4e753a 100644 (file)
        "rollbacklinkcount-morethan": "回退超过$1次的编辑",
        "rollbackfailed": "回退失败",
        "rollback-missingparam": "请求中缺少必需参数。",
+       "rollback-missingrevision": "无法加载修订版本数据。",
        "cantrollback": "无法恢复编辑,最后贡献者是该页面的唯一作者。",
        "alreadyrolled": "无法回退[[User:$2|$2]]([[User talk:$2|讨论]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])对[[:$1]]的编辑,其他人已经编辑或者回退了该页。\n\n本页最后的编辑者是[[User:$3|$3]]([[User talk:$3|讨论]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])。",
        "editcomment": "编辑摘要:<em>$1</em>。",
        "linkaccounts-submit": "链接帐户",
        "unlinkaccounts": "取消链接账户",
        "unlinkaccounts-success": "账户已取消链接。",
-       "authenticationdatachange-ignored": "身份验证数据更改未处理。也许没有配置的提供者?"
+       "authenticationdatachange-ignored": "身份验证数据更改未处理。也许没有配置的提供者?",
+       "userjsispublic": "请注意:JavaScript子页面不应包含机密数据,因为它们可以被其他用户查看。",
+       "usercssispublic": "请注意:CSS子页面不应包含机密数据,因为它们可以被其他用户查看。"
 }
diff --git a/maintenance/archives/patch-pl-tl-il-nonunique.sql b/maintenance/archives/patch-pl-tl-il-nonunique.sql
new file mode 100644 (file)
index 0000000..8e1715b
--- /dev/null
@@ -0,0 +1,11 @@
+-- Make reorderings of UNIQUE indices non-UNIQUE
+-- Since 1.24, these indices have been non-UNIQUE in tables.sql.
+-- However, an earlier update from 1.15 that made the indices
+-- UNIQUE was not removed until 1.28 (T78513).
+
+DROP INDEX /*i*/pl_namespace ON /*_*/pagelinks;
+CREATE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace, pl_title, pl_from);
+DROP INDEX /*i*/tl_namespace ON /*_*/templatelinks;
+CREATE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace, tl_title, tl_from);
+DROP INDEX /*i*/il_to ON /*_*/imagelinks;
+CREATE INDEX /*i*/il_to ON /*_*/imagelinks (il_to, il_from);
diff --git a/maintenance/archives/patch-pl-tl-il-unique.sql b/maintenance/archives/patch-pl-tl-il-unique.sql
deleted file mode 100644 (file)
index a356670..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---
--- patch-pl-tl-il-unique-index.sql
---
--- Make reorderings of UNIQUE indices UNIQUE as well
-
-DROP INDEX /*i*/pl_namespace ON /*_*/pagelinks;
-CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace, pl_title, pl_from);
-DROP INDEX /*i*/tl_namespace ON /*_*/templatelinks;
-CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace, tl_title, tl_from);
-DROP INDEX /*i*/il_to ON /*_*/imagelinks;
-CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to, il_from);
diff --git a/maintenance/archives/patch-revision-page-rev-index-nonunique.sql b/maintenance/archives/patch-revision-page-rev-index-nonunique.sql
new file mode 100644 (file)
index 0000000..dbb0325
--- /dev/null
@@ -0,0 +1,5 @@
+-- Makes rev_page_id index non-unique
+ALTER TABLE /*_*/revision
+DROP INDEX /*i*/rev_page_id;
+
+CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
index 454c506..e74a86c 100644 (file)
@@ -132,7 +132,7 @@ class SqliteMaintenance extends Maintenance {
                        $this->error( "Error: SQLite support not found\n" );
                }
                $files = [ $this->getOption( 'check-syntax' ) ];
-               $files += $this->mArgs;
+               $files = array_merge( $files, $this->mArgs );
                $result = Sqlite::checkSqlSyntax( $files );
                if ( $result === true ) {
                        $this->output( "SQL syntax check: no errors detected.\n" );
index 40506bf..b5c14e3 100644 (file)
@@ -369,7 +369,7 @@ CREATE TABLE /*_*/revision (
 ) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
 -- In case tables are created as MyISAM, use row hints for MySQL <5.0 to avoid 4GB limit
 
-CREATE UNIQUE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
+CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
 CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
 CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
 CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
index 922cc87..930f533 100644 (file)
@@ -101,7 +101,7 @@ TEXT
                        'STRAIGHT_JOIN' // per T58041
                ];
 
-               if ( $force || $dryRun ) {
+               if ( $force ) {
                        $collationConds = [];
                } else {
                        if ( $this->hasOption( 'previous-collation' ) ) {
@@ -132,7 +132,11 @@ TEXT
 
                                return;
                        }
-                       $this->output( "Fixing collation for $count rows.\n" );
+                       if ( $dryRun ) {
+                               $this->output( "$count rows would be updated.\n" );
+                       } else {
+                               $this->output( "Fixing collation for $count rows.\n" );
+                       }
                        wfWaitForSlaves();
                }
                $count = 0;
index cfaaf5f..ef56cd3 100644 (file)
@@ -160,6 +160,9 @@ return [
                'targets' => [ 'mobile', 'desktop' ],
        ],
        'jquery.appear' => [
+               'deprecated' => [
+                       'message' => 'Please use "mediawiki.viewport" instead.',
+               ],
                'scripts' => 'resources/lib/jquery/jquery.appear.js',
        ],
        'jquery.arrowSteps' => [
@@ -567,6 +570,7 @@ return [
                'group' => 'jquery.ui',
        ],
        'jquery.ui.position' => [
+               'deprecated' => true,
                'scripts' => 'resources/lib/jquery.ui/jquery.ui.position.js',
                'group' => 'jquery.ui',
        ],
@@ -980,11 +984,6 @@ return [
                'dependencies' => [
                        'jquery.footHovzer',
                ],
-               'position' => 'bottom',
-       ],
-       'mediawiki.debug.init' => [
-               'scripts' => 'resources/src/mediawiki/mediawiki.debug.init.js',
-               'dependencies' => 'mediawiki.debug',
                // Uses a custom mw.config variable that is set in debughtml,
                // must be loaded on the bottom
                'position' => 'bottom',
index 3d90307..5c3715d 100644 (file)
 
                capsuleWidget: {
                        getApiValue: function () {
-                               return this.getItemsData().join( '|' );
+                               var items = this.getItemsData();
+                               if ( items.join( '' ).indexOf( '|' ) === -1 ) {
+                                       return items.join( '|' );
+                               } else {
+                                       return '\x1f' + items.join( '\x1f' );
+                               }
                        },
                        setApiValue: function ( v ) {
-                               this.setItemsFromData( v === undefined || v === '' ? [] : String( v ).split( '|' ) );
+                               if ( v === undefined || v === '' || v === '\x1f' ) {
+                                       this.setItemsFromData( [] );
+                               } else {
+                                       v = String( v );
+                                       if ( v.indexOf( '\x1f' ) !== 0 ) {
+                                               this.setItemsFromData( v.split( '|' ) );
+                                       } else {
+                                               this.setItemsFromData( v.substr( 1 ).split( '\x1f' ) );
+                                       }
+                               }
                        },
                        apiCheckValid: function () {
                                var ok = this.getApiValue() !== undefined || suppressErrors;
index 946823d..4d86cfd 100644 (file)
                        prop: [ 'info' ],
                        titles: titles
                } ).done( function ( response ) {
+                       var
+                               normalized = {},
+                               pages = {};
+                       $.each( response.query.normalized || [], function ( index, data ) {
+                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
+                       } );
                        $.each( response.query.pages, function ( index, page ) {
-                               var title = new ForeignTitle( page.title ).getPrefixedText();
-                               cache.existenceCache[ title ] = !page.missing;
-                               if ( !queue[ title ] ) {
-                                       // Debugging for T139130
-                                       throw new Error( 'No queue for "' + title + '", requested "' + titles.join( '|' ) + '"' );
+                               pages[ page.title ] = !page.missing;
+                       } );
+                       $.each( titles, function ( index, title ) {
+                               var normalizedTitle = title;
+                               while ( normalized[ normalizedTitle ] ) {
+                                       normalizedTitle = normalized[ normalizedTitle ];
                                }
+                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
                                queue[ title ].resolve( cache.existenceCache[ title ] );
                        } );
                } );
index a8ee4c7..b7579ff 100644 (file)
@@ -9,6 +9,9 @@
         *     `options` to mw.Api constructor.
         * @property {Object} defaultOptions.parameters Default query parameters for API requests.
         * @property {Object} defaultOptions.ajax Default options for jQuery#ajax.
+        * @property {boolean} defaultOptions.useUS Whether to use U+001F when joining multi-valued
+        *     parameters (since 1.28). Default is true if ajax.url is not set, false otherwise for
+        *     compatibility.
         * @private
         */
        var defaultOptions = {
@@ -95,6 +98,8 @@
                        options.ajax.url = String( options.ajax.url );
                }
 
+               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
+
                options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
                options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
 
                 *
                 * @private
                 * @param {Object} parameters (modified in-place)
+                * @param {boolean} useUS Whether to use U+001F when joining multi-valued parameters.
                 */
-               preprocessParameters: function ( parameters ) {
+               preprocessParameters: function ( parameters, useUS ) {
                        var key;
                        // Handle common MediaWiki API idioms for passing parameters
                        for ( key in parameters ) {
                                // Multiple values are pipe-separated
                                if ( $.isArray( parameters[ key ] ) ) {
-                                       parameters[ key ] = parameters[ key ].join( '|' );
+                                       if ( !useUS || parameters[ key ].join( '' ).indexOf( '|' ) === -1 ) {
+                                               parameters[ key ] = parameters[ key ].join( '|' );
+                                       } else {
+                                               parameters[ key ] = '\x1f' + parameters[ key ].join( '\x1f' );
+                                       }
                                }
                                // Boolean values are only false when not given at all
                                if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
                                delete parameters.token;
                        }
 
-                       this.preprocessParameters( parameters );
+                       this.preprocessParameters( parameters, this.defaults.useUS );
 
                        // If multipart/form-data has been requested and emulation is possible, emulate it
                        if (
index 9ba562e..a1a4999 100644 (file)
                 * Get a set of messages.
                 *
                 * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
                 * @return {jQuery.Promise}
                 */
-               getMessages: function ( messages ) {
-                       return this.get( {
+               getMessages: function ( messages, options ) {
+                       options = options || {};
+                       return this.get( $.extend( {
                                action: 'query',
                                meta: 'allmessages',
                                ammessages: messages,
                                amlang: mw.config.get( 'wgUserLanguage' ),
                                formatversion: 2
-                       } ).then( function ( data ) {
+                       }, options ) ).then( function ( data ) {
                                var result = {};
 
                                $.each( data.query.allmessages, function ( i, obj ) {
                },
 
                /**
-                * Loads a set of mesages and add them to mw.messages.
+                * Loads a set of messages and add them to mw.messages.
                 *
                 * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
                 * @return {jQuery.Promise}
                 */
-               loadMessages: function ( messages ) {
-                       return this.getMessages( messages ).then( $.proxy( mw.messages, 'set' ) );
+               loadMessages: function ( messages, options ) {
+                       return this.getMessages( messages, options ).then( $.proxy( mw.messages, 'set' ) );
                },
 
                /**
-                * Loads a set of mesages and add them to mw.messages. Only messages that are not already known
+                * Loads a set of messages and add them to mw.messages. Only messages that are not already known
                 * are loaded. If all messages are known, the returned promise is resolved immediately.
                 *
                 * @param {Array} messages Messages to retrieve
+                * @param {Object} [options] Additional parameters for the API call
                 * @return {jQuery.Promise}
                 */
-               loadMessagesIfMissing: function ( messages ) {
+               loadMessagesIfMissing: function ( messages, options ) {
                        var missing = messages.filter( function ( msg ) {
                                return !mw.message( msg ).exists();
                        } );
@@ -62,7 +66,7 @@
                                return $.Deferred().resolve();
                        }
 
-                       return this.getMessages( missing ).then( $.proxy( mw.messages, 'set' ) );
+                       return this.getMessages( missing, options ).then( $.proxy( mw.messages, 'set' ) );
                }
        } );
 
index 0af2a75..069fbbf 100644 (file)
                                value = options[ name ] === null ? null : String( options[ name ] );
 
                                // Can we bundle this option, or does it need a separate request?
-                               bundleable =
-                                       ( value === null || value.indexOf( '|' ) === -1 ) &&
-                                       ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
+                               if ( this.defaults.useUS ) {
+                                       bundleable = name.indexOf( '=' ) === -1;
+                               } else {
+                                       bundleable =
+                                               ( value === null || value.indexOf( '|' ) === -1 ) &&
+                                               ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
+                               }
 
                                if ( bundleable ) {
                                        if ( value !== null ) {
index cb717af..0fbbcbe 100644 (file)
                                }
                                v = spec[ 2 ];
 
-                               if ( field instanceof OO.ui.Widget ) {
+                               if ( !( field instanceof jQuery ) ) {
+                                       // field is a OO.ui.Widget
                                        if ( field.supports( 'isSelected' ) ) {
                                                getVal = function () {
                                                        var selected = field.isSelected();
index a9e75d7..fc0fd6e 100644 (file)
@@ -1,9 +1,5 @@
 /* OOUIHTMLForm styles */
 
-.mw-htmlform-ooui-wrapper {
-       margin: 1em 0;
-}
-
 .mw-htmlform-ooui .mw-htmlform-submit-buttons {
        margin-top: 1em;
 }
diff --git a/resources/src/mediawiki/mediawiki.debug.init.js b/resources/src/mediawiki/mediawiki.debug.init.js
deleted file mode 100644 (file)
index 0f85e80..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-jQuery( function () {
-       mediaWiki.Debug.init();
-} );
index f721009..26c74a1 100644 (file)
                }
        };
 
+       $( function () {
+               debug.init();
+       } );
+
 }( mediaWiki, jQuery ) );
index fdb7adf..a74aef3 100644 (file)
                                        $.extend( stats, mw.loader.store.stats );
                                        try {
                                                raw = localStorage.getItem( mw.loader.store.getStoreKey() );
+                                               stats.totalSizeInBytes =  $.byteLength( raw );
                                                stats.totalSize = humanSize( $.byteLength( raw ) );
                                        } catch ( e ) {}
                                }
index 491564a..af37162 100644 (file)
                                                j -= 1;
                                                try {
                                                        if ( hasErrors ) {
-                                                               if ( $.isFunction( job.error ) ) {
+                                                               if ( typeof job.error === 'function' ) {
                                                                        job.error( new Error( 'Module ' + module + ' has failed dependencies' ), [ module ] );
                                                                }
                                                        } else {
-                                                               if ( $.isFunction( job.ready ) ) {
+                                                               if ( typeof job.ready === 'function' ) {
                                                                        job.ready();
                                                                }
                                                        }
                                }
 
                                // Resolves dynamic loader function and replaces it with its own results
-                               if ( $.isFunction( registry[ module ].dependencies ) ) {
+                               if ( typeof registry[ module ].dependencies === 'function' ) {
                                        registry[ module ].dependencies = registry[ module ].dependencies();
                                        // Ensures the module's dependencies are always in an array
                                        if ( typeof registry[ module ].dependencies !== 'object' ) {
                                                legacyWait.always( function () {
                                                        if ( $.isArray( script ) ) {
                                                                nestedAddScript( script, markModuleReady, 0 );
-                                                       } else if ( $.isFunction( script ) ) {
+                                                       } else if ( typeof script === 'function' ) {
                                                                // Pass jQuery twice so that the signature of the closure which wraps
                                                                // the script can bind both '$' and 'jQuery'.
                                                                script( $, $, mw.loader.require, registry[ module ].module );
                         * @param {Array} modules Modules array
                         */
                        function resolveIndexedDependencies( modules ) {
-                               $.each( modules, function ( idx, module ) {
-                                       if ( module[ 2 ] ) {
-                                               module[ 2 ] = $.map( module[ 2 ], function ( dep ) {
-                                                       return typeof dep === 'number' ? modules[ dep ][ 0 ] : dep;
-                                               } );
+                               var i, j, deps;
+                               function resolveIndex( dep ) {
+                                       return typeof dep === 'number' ? modules[ dep ][ 0 ] : dep;
+                               }
+                               for ( i = 0; i < modules.length; i++ ) {
+                                       deps = modules[ i ][ 2 ];
+                                       if ( deps ) {
+                                               for ( j = 0; j < deps.length; j++ ) {
+                                                       deps[ j ] = resolveIndex( deps[ j ] );
+                                               }
                                        }
-                               } );
+                               }
                        }
 
                        /**
                                 * @param {string} [skip=null] Script body of the skip function
                                 */
                                register: function ( module, version, dependencies, group, source, skip ) {
-                                       var i;
+                                       var i, deps;
                                        // Allow multiple registration
                                        if ( typeof module === 'object' ) {
                                                resolveIndexedDependencies( module );
                                        if ( hasOwn.call( registry, module ) ) {
                                                throw new Error( 'module already registered: ' + module );
                                        }
+                                       if ( typeof dependencies === 'string' ) {
+                                               // A single module name
+                                               deps = [ dependencies ];
+                                       } else if ( typeof dependencies === 'object' || typeof dependencies === 'function' ) {
+                                               // Array of module names or a function that returns an array
+                                               deps = dependencies;
+                                       }
                                        // List the module as registered
                                        registry[ module ] = {
                                                // Exposed to execute() for mw.loader.implement() closures.
                                                        exports: {}
                                                },
                                                version: version !== undefined ? String( version ) : '',
-                                               dependencies: [],
+                                               dependencies: deps || [],
                                                group: typeof group === 'string' ? group : null,
                                                source: typeof source === 'string' ? source : 'local',
                                                state: 'registered',
                                                skip: typeof skip === 'string' ? skip : null
                                        };
-                                       if ( typeof dependencies === 'string' ) {
-                                               // Allow dependencies to be given as a single module name
-                                               registry[ module ].dependencies = [ dependencies ];
-                                       } else if ( typeof dependencies === 'object' || $.isFunction( dependencies ) ) {
-                                               // Allow dependencies to be given as an array of module names
-                                               // or a function which returns an array
-                                               registry[ module ].dependencies = dependencies;
-                                       }
                                },
 
                                /**
                                        if ( !hasOwn.call( registry, module ) ) {
                                                mw.loader.register( module );
                                        }
-                                       if ( $.inArray( state, [ 'ready', 'error', 'missing' ] ) !== -1
-                                               && registry[ module ].state !== state ) {
+                                       registry[ module ].state = state;
+                                       if ( $.inArray( state, [ 'ready', 'error', 'missing' ] ) !== -1 ) {
                                                // Make sure pending modules depending on this one get executed if their
                                                // dependencies are now fulfilled!
-                                               registry[ module ].state = state;
                                                handlePending( module );
-                                       } else {
-                                               registry[ module ].state = state;
                                        }
                                },
 
                                                        // Unversioned, private, or site-/user-specific
                                                        ( !descriptor.version || $.inArray( descriptor.group, [ 'private', 'user' ] ) !== -1 ) ||
                                                        // Partial descriptor
+                                                       // (e.g. skipped module, or style module with state=ready)
                                                        $.inArray( undefined, [ descriptor.script, descriptor.style,
                                                                        descriptor.messages, descriptor.templates ] ) !== -1
                                                ) {
index 78627fc..7bf73b6 100644 (file)
@@ -10,7 +10,8 @@
                $tocList = $toc.find( 'ul' ).eq( 0 );
 
                // Hide/show the table of contents element
-               function toggleToc() {
+               function toggleToc( e ) {
+                       e.preventDefault();
                        if ( $tocList.is( ':hidden' ) ) {
                                $tocList.slideDown( 'fast' );
                                $tocToggleLink.text( mw.msg( 'hidetoc' ) );
                        hideToc = mw.cookie.get( 'hidetoc' ) === '1';
 
                        $tocToggleLink = $( '<a href="#" id="togglelink"></a>' )
-                               .text( hideToc ? mw.msg( 'showtoc' ) : mw.msg( 'hidetoc' ) )
-                               .click( function ( e ) {
-                                       e.preventDefault();
-                                       toggleToc();
-                               } );
+                               .text( mw.msg( hideToc ? 'showtoc' : 'hidetoc' ) )
+                               .click( toggleToc );
 
                        $tocTitle.append(
                                $tocToggleLink
index 5d1ead0..8b75d56 100644 (file)
@@ -43,4 +43,87 @@ class ApiBaseTest extends ApiTestCase {
                );
        }
 
+       /**
+        * @dataProvider provideGetParameterFromSettings
+        * @param string|null $input
+        * @param array $paramSettings
+        * @param mixed $expected
+        * @param string[] $warnings
+        */
+       public function testGetParameterFromSettings( $input, $paramSettings, $expected, $warnings ) {
+               $mock = new MockApi();
+               $wrapper = TestingAccessWrapper::newFromObject( $mock );
+
+               $context = new DerivativeContext( $mock );
+               $context->setRequest( new FauxRequest( $input !== null ? [ 'foo' => $input ] : [] ) );
+               $wrapper->mMainModule = new ApiMain( $context );
+
+               if ( $expected instanceof UsageException ) {
+                       try {
+                               $wrapper->getParameterFromSettings( 'foo', $paramSettings, true );
+                       } catch ( UsageException $ex ) {
+                               $this->assertEquals( $expected, $ex );
+                       }
+               } else {
+                       $result = $wrapper->getParameterFromSettings( 'foo', $paramSettings, true );
+                       $this->assertSame( $expected, $result );
+                       $this->assertSame( $warnings, $mock->warnings );
+               }
+       }
+
+       public static function provideGetParameterFromSettings() {
+               $warnings = [
+                       'The value passed for \'foo\' contains invalid or non-normalized data. Textual data should ' .
+                       'be valid, NFC-normalized Unicode without C0 control characters other than ' .
+                       'HT (\\t), LF (\\n), and CR (\\r).'
+               ];
+
+               $c0 = '';
+               $enc = '';
+               for ( $i = 0; $i < 32; $i++ ) {
+                       $c0 .= chr( $i );
+                       $enc .= ( $i === 9 || $i === 10 || $i === 13 )
+                               ? chr( $i )
+                               : '�';
+               }
+
+               return [
+                       'Basic param' => [ 'bar', null, 'bar', [] ],
+                       'Basic param, C0 controls' => [ $c0, null, $enc, $warnings ],
+                       'String param' => [ 'bar', '', 'bar', [] ],
+                       'String param, defaulted' => [ null, '', '', [] ],
+                       'String param, empty' => [ '', 'default', '', [] ],
+                       'String param, required, empty' => [
+                               '',
+                               [ ApiBase::PARAM_DFLT => 'default', ApiBase::PARAM_REQUIRED => true ],
+                               new UsageException( 'The foo parameter must be set', 'nofoo' ),
+                               []
+                       ],
+                       'Multi-valued parameter' => [
+                               'a|b|c',
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ 'a', 'b', 'c' ],
+                               []
+                       ],
+                       'Multi-valued parameter, alternative separator' => [
+                               "\x1fa|b\x1fc|d",
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ 'a|b', 'c|d' ],
+                               []
+                       ],
+                       'Multi-valued parameter, other C0 controls' => [
+                               $c0,
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ $enc ],
+                               $warnings
+                       ],
+                       'Multi-valued parameter, other C0 controls (2)' => [
+                               "\x1f" . $c0,
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ substr( $enc, 0, -3 ), '' ],
+                               $warnings
+                       ],
+               ];
+       }
+
 }
index 18da5af..d13b00b 100644 (file)
@@ -132,7 +132,7 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'err' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        $I => 'error',
@@ -142,7 +142,7 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'string' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        $I => 'warning',
@@ -154,7 +154,7 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'errWithData' => [
                                                        [
                                                                'code' => 'overriddenCode',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ],
                                                                'overriddenData' => true
                                                        ],
@@ -165,7 +165,7 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'messageWithData' => [
                                                        [
                                                                'code' => 'overriddenCode',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ],
                                                                'overriddenData' => true
                                                        ],
@@ -174,7 +174,7 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'message' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        $I => 'warning',
@@ -182,12 +182,12 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'foo' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        [
                                                                'code' => 'parentheses',
-                                                               'message' => 'parentheses',
+                                                               'key' => 'parentheses',
                                                                'params' => [ 'foobar', $I => 'param' ]
                                                        ],
                                                        $I => 'warning',
@@ -199,12 +199,12 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'status' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        [
                                                                'code' => 'parentheses',
-                                                               'message' => 'parentheses',
+                                                               'key' => 'parentheses',
                                                                'params' => [ 'foobar', $I => 'param' ]
                                                        ],
                                                        $I => 'error',
@@ -214,17 +214,17 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                                'status' => [
                                                        [
                                                                'code' => 'mainpage',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ]
                                                        ],
                                                        [
                                                                'code' => 'parentheses',
-                                                               'message' => 'parentheses',
+                                                               'key' => 'parentheses',
                                                                'params' => [ 'foobar', $I => 'param' ]
                                                        ],
                                                        [
                                                                'code' => 'overriddenCode',
-                                                               'message' => 'mainpage',
+                                                               'key' => 'mainpage',
                                                                'params' => [ $I => 'param' ],
                                                                'overriddenData' => true
                                                        ],
index 367210a..ad1deee 100644 (file)
@@ -75,4 +75,25 @@ class ApiPageSetTest extends ApiTestCase {
 
                return [ $target, $pageSet ];
        }
+
+       public function testHandleNormalization() {
+               $context = new RequestContext();
+               $context->setRequest( new FauxRequest( [ 'titles' => "a|B|a\xcc\x8a" ] ) );
+               $main = new ApiMain( $context );
+               $pageSet = new ApiPageSet( $main );
+               $pageSet->execute();
+
+               $this->assertSame(
+                       [ 0 => [ 'A' => -1, 'B' => -2, 'Å' => -3 ] ],
+                       $pageSet->getAllTitlesByNamespace()
+               );
+               $this->assertSame(
+                       [
+                               [ 'fromencoded' => true, 'from' => 'a%CC%8A', 'to' => 'å' ],
+                               [ 'fromencoded' => false, 'from' => 'a', 'to' => 'A' ],
+                               [ 'fromencoded' => false, 'from' => 'å', 'to' => 'Å' ],
+                       ],
+                       $pageSet->getNormalizedTitlesAsResult()
+               );
+       }
 }
index 9a64d08..d7db538 100644 (file)
@@ -1,12 +1,18 @@
 <?php
 
 class MockApi extends ApiBase {
+       public $warnings = [];
+
        public function execute() {
        }
 
        public function __construct() {
        }
 
+       public function setWarning( $warning ) {
+               $this->warnings[] = $warning;
+       }
+
        public function getAllowedParams() {
                return [
                        'filename' => null,
index 504b16a..8cb2327 100644 (file)
@@ -43,6 +43,7 @@ class ApiQueryTest extends ApiTestCase {
 
                $this->assertEquals(
                        [
+                               'fromencoded' => false,
                                'from' => 'Project:articleA',
                                'to' => $to->getPrefixedText(),
                        ],
@@ -51,6 +52,7 @@ class ApiQueryTest extends ApiTestCase {
 
                $this->assertEquals(
                        [
+                               'fromencoded' => false,
                                'from' => 'article_B',
                                'to' => 'Article B'
                        ],
index bc7542a..607f25c 100644 (file)
@@ -31,6 +31,8 @@
 class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
        // From DatabaseBase
        function __construct() {
+               $this->profiler = new ProfilerStub( [] );
+               $this->trxProfiler = new TransactionProfiler();
        }
 
        protected function closeConnection() {
index aa8b8e8..d6ca596 100644 (file)
@@ -27,6 +27,9 @@ class DatabaseTestHelper extends DatabaseBase {
 
        public function __construct( $testName ) {
                $this->testName = $testName;
+
+               $this->profiler = new ProfilerStub( [] );
+               $this->trxProfiler = new TransactionProfiler();
        }
 
        /**
index e7abd15..ad84c20 100644 (file)
@@ -712,6 +712,7 @@ class NewParserTest extends MediaWikiTestCase {
                if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) {
                        $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions"
                        // $this->markTestSkipped( 'Filtered out by the user' );
+                       $this->teardownGlobals();
                        return;
                }
 
@@ -719,6 +720,7 @@ class NewParserTest extends MediaWikiTestCase {
                        // parser tests frequently assume that the main namespace contains wikitext.
                        // @todo When setting up pages, force the content model. Only skip if
                        //        $wgtContentModelUseDB is false.
+                       $this->teardownGlobals();
                        $this->markTestSkipped( "Main namespace does not support wikitext,"
                                . "skipping parser test: $desc" );
                }
@@ -749,8 +751,10 @@ class NewParserTest extends MediaWikiTestCase {
                        global $wgTexvc;
 
                        if ( !isset( $wgTexvc ) ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: \$wgTexvc is not set" );
                        } elseif ( !is_executable( $wgTexvc ) ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: texvc binary does not exist"
                                        . " or is not executable.\n"
                                        . "Current configuration is:\n\$wgTexvc = '$wgTexvc'" );
@@ -759,12 +763,14 @@ class NewParserTest extends MediaWikiTestCase {
 
                if ( isset( $opts['djvu'] ) ) {
                        if ( !$this->djVuSupport->isEnabled() ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: djvu binaries do not exist or are not executable.\n" );
                        }
                }
 
                if ( isset( $opts['tidy'] ) ) {
                        if ( !$this->tidySupport->isEnabled() ) {
+                               $this->teardownGlobals();
                                $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
                        } else {
                                $options->setTidy( true );
index a62503a..6710b19 100644 (file)
@@ -1,5 +1,29 @@
 <?php
 
+/**
+ * @covers Preprocessor
+ *
+ * @covers Preprocessor_DOM
+ * @covers PPDStack
+ * @covers PPDStackElement
+ * @covers PPDPart
+ * @covers PPFrame_DOM
+ * @covers PPTemplateFrame_DOM
+ * @covers PPCustomFrame_DOM
+ * @covers PPNode_DOM
+ *
+ * @covers Preprocessor_Hash
+ * @covers PPDStack_Hash
+ * @covers PPDStackElement_Hash
+ * @covers PPDPart_Hash
+ * @covers PPFrame_Hash
+ * @covers PPTemplateFrame_Hash
+ * @covers PPCustomFrame_Hash
+ * @covers PPNode_Hash_Tree
+ * @covers PPNode_Hash_Text
+ * @covers PPNode_Hash_Array
+ * @covers PPNode_Hash_Attr
+ */
 class PreprocessorTest extends MediaWikiTestCase {
        protected $mTitle = 'Page title';
        protected $mPPNodeCount = 0;
@@ -8,28 +32,44 @@ class PreprocessorTest extends MediaWikiTestCase {
         */
        protected $mOptions;
        /**
-        * @var Preprocessor
+        * @var array
         */
-       protected $mPreprocessor;
+       protected $mPreprocessors;
+
+       protected static $classNames = [
+               'Preprocessor_DOM',
+               'Preprocessor_Hash'
+       ];
 
        protected function setUp() {
-               global $wgParserConf, $wgContLang;
+               global $wgContLang;
                parent::setUp();
                $this->mOptions = ParserOptions::newFromUserAndLang( new User, $wgContLang );
-               $name = isset( $wgParserConf['preprocessorClass'] )
-                       ? $wgParserConf['preprocessorClass']
-                       : 'Preprocessor_DOM';
 
-               $this->mPreprocessor = new $name( $this );
+               $this->mPreprocessors = [];
+               foreach ( self::$classNames as $className ) {
+                       $this->mPreprocessors[$className] = new $className( $this );
+               }
        }
 
        function getStripList() {
                return [ 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' ];
        }
 
+       protected static function addClassArg( $testCases ) {
+               $newTestCases = [];
+               foreach ( self::$classNames as $className ) {
+                       foreach ( $testCases as $testCase ) {
+                               array_unshift( $testCase, $className );
+                               $newTestCases[] = $testCase;
+                       }
+               }
+               return $newTestCases;
+       }
+
        public static function provideCases() {
                // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
-               return [
+               return self::addClassArg( [
                        [ "Foo", "<root>Foo</root>" ],
                        [ "<!-- Foo -->", "<root><comment>&lt;!-- Foo --&gt;</comment></root>" ],
                        [ "<!-- Foo --><!-- Bar -->", "<root><comment>&lt;!-- Foo --&gt;</comment><comment>&lt;!-- Bar --&gt;</comment></root>" ],
@@ -115,7 +155,7 @@ class PreprocessorTest extends MediaWikiTestCase {
                        [ "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>" ],
                        [ "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>" ],
                        /* [ file_get_contents( __DIR__ . '/QuoteQuran.txt' ], file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ], */
-               ];
+               ] );
                // @codingStandardsIgnoreEnd
        }
 
@@ -123,15 +163,17 @@ class PreprocessorTest extends MediaWikiTestCase {
         * Get XML preprocessor tree from the preprocessor (which may not be the
         * native XML-based one).
         *
+        * @param string $className
         * @param string $wikiText
         * @return string
         */
-       protected function preprocessToXml( $wikiText ) {
-               if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) {
-                       return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) );
+       protected function preprocessToXml( $className, $wikiText ) {
+               $preprocessor = $this->mPreprocessors[$className];
+               if ( method_exists( $preprocessor, 'preprocessToXml' ) ) {
+                       return $this->normalizeXml( $preprocessor->preprocessToXml( $wikiText ) );
                }
 
-               $dom = $this->mPreprocessor->preprocessToObj( $wikiText );
+               $dom = $preprocessor->preprocessToObj( $wikiText );
                if ( is_callable( [ $dom, 'saveXML' ] ) ) {
                        return $dom->saveXML();
                } else {
@@ -146,15 +188,20 @@ class PreprocessorTest extends MediaWikiTestCase {
         * @return string
         */
        protected function normalizeXml( $xml ) {
-               return preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) );
+               // Normalize self-closing tags
+               $xml = preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) );
+               // Remove <equals> tags, which only occur in Preprocessor_Hash and
+               // have no semantic value
+               $xml = preg_replace( '!</?equals>!', '', $xml );
+               return $xml;
        }
 
        /**
         * @dataProvider provideCases
-        * @covers Preprocessor_DOM::preprocessToXml
         */
-       public function testPreprocessorOutput( $wikiText, $expectedXml ) {
-               $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
+       public function testPreprocessorOutput( $className, $wikiText, $expectedXml ) {
+               $this->assertEquals( $this->normalizeXml( $expectedXml ),
+                       $this->preprocessToXml( $className, $wikiText ) );
        }
 
        /**
@@ -162,24 +209,23 @@ class PreprocessorTest extends MediaWikiTestCase {
         */
        public static function provideFiles() {
                // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
-               return [
+               return self::addClassArg( [
                        [ "QuoteQuran" ], # http://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC BY-SA by Striver
                        [ "Factorial" ], # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC BY-SA by Polonium
                        [ "All_system_messages" ], # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
                        [ "Fundraising" ], # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC BY-SA, copied there by Sky Harbor.
                        [ "NestedTemplates" ], # bug 27936
-               ];
+               ] );
                // @codingStandardsIgnoreEnd
        }
 
        /**
         * @dataProvider provideFiles
-        * @covers Preprocessor_DOM::preprocessToXml
         */
-       public function testPreprocessorOutputFiles( $filename ) {
+       public function testPreprocessorOutputFiles( $className, $filename ) {
                $folder = __DIR__ . "/../../../parser/preprocess";
                $wikiText = file_get_contents( "$folder/$filename.txt" );
-               $output = $this->preprocessToXml( $wikiText );
+               $output = $this->preprocessToXml( $className, $wikiText );
 
                $expectedFilename = "$folder/$filename.expected";
                if ( file_exists( $expectedFilename ) ) {
@@ -197,7 +243,8 @@ class PreprocessorTest extends MediaWikiTestCase {
         */
        public static function provideHeadings() {
                // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
-               return [ /* These should become headings: */
+               return self::addClassArg( [
+                       /* These should become headings: */
                        [ "== h ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment></h></root>" ],
                        [ "== h ==      <!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==       <comment>&lt;!--c1--&gt;</comment></h></root>" ],
                        [ "== h ==<!--c1-->     ", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment>      </h></root>" ],
@@ -233,15 +280,15 @@ class PreprocessorTest extends MediaWikiTestCase {
                        [ "== h == x <!--c1--><!--c2--><!--c3-->  ", "<root>== h == x <comment>&lt;!--c1--&gt;</comment><comment>&lt;!--c2--&gt;</comment><comment>&lt;!--c3--&gt;</comment>  </root>" ],
                        [ "== h ==<!--c1--> x <!--c2--><!--c3-->  ", "<root>== h ==<comment>&lt;!--c1--&gt;</comment> x <comment>&lt;!--c2--&gt;</comment><comment>&lt;!--c3--&gt;</comment>  </root>" ],
                        [ "== h ==<!--c1--><!--c2--><!--c3--> x ", "<root>== h ==<comment>&lt;!--c1--&gt;</comment><comment>&lt;!--c2--&gt;</comment><comment>&lt;!--c3--&gt;</comment> x </root>" ],
-               ];
+               ] );
                // @codingStandardsIgnoreEnd
        }
 
        /**
         * @dataProvider provideHeadings
-        * @covers Preprocessor_DOM::preprocessToXml
         */
-       public function testHeadings( $wikiText, $expectedXml ) {
-               $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
+       public function testHeadings( $className, $wikiText, $expectedXml ) {
+               $this->assertEquals( $this->normalizeXml( $expectedXml ),
+                       $this->preprocessToXml( $className, $wikiText ) );
        }
 }
index 90c9f38..0be04ef 100644 (file)
@@ -2,11 +2,11 @@
 
 /**
  * @group ResourceLoader
+ * @covers DerivativeResourceLoaderContext
  */
 class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
 
-       protected static function getResourceLoaderContext() {
-               $resourceLoader = new ResourceLoader();
+       protected static function getContext() {
                $request = new FauxRequest( [
                                'lang' => 'zh',
                                'modules' => 'test.context',
@@ -14,42 +14,76 @@ class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
                                'skin' => 'fallback',
                                'target' => 'test',
                ] );
-               return new ResourceLoaderContext( $resourceLoader, $request );
+               return new ResourceLoaderContext( new ResourceLoader(), $request );
        }
 
-       public function testGet() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testGetInherited() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
+               // Request parameters
+               $this->assertEquals( $derived->getDebug(), false );
                $this->assertEquals( $derived->getLanguage(), 'zh' );
                $this->assertEquals( $derived->getModules(), [ 'test.context' ] );
                $this->assertEquals( $derived->getOnly(), 'scripts' );
                $this->assertEquals( $derived->getSkin(), 'fallback' );
+               $this->assertEquals( $derived->getUser(), null );
+
+               // Misc
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
                $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
        }
 
-       public function testSetLanguage() {
-               $context = self::getResourceLoaderContext();
+       public function testModules() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setModules( [ 'test.override' ] );
+               $this->assertEquals( $derived->getModules(), [ 'test.override' ] );
+       }
+
+       public function testLanguage() {
+               $context = self::getContext();
                $derived = new DerivativeResourceLoaderContext( $context );
 
                $derived->setLanguage( 'nl' );
                $this->assertEquals( $derived->getLanguage(), 'nl' );
+       }
+
+       public function testDirection() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setLanguage( 'nl' );
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
 
                $derived->setLanguage( 'he' );
                $this->assertEquals( $derived->getDirection(), 'rtl' );
+
+               $derived->setDirection( 'ltr' );
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
        }
 
-       public function testSetModules() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testSkin() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
-               $derived->setModules( [ 'test.override' ] );
-               $this->assertEquals( $derived->getModules(), [ 'test.override' ] );
+               $derived->setSkin( 'override' );
+               $this->assertEquals( $derived->getSkin(), 'override' );
        }
 
-       public function testSetOnly() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testUser() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setUser( 'Example' );
+               $this->assertEquals( $derived->getUser(), 'Example' );
+       }
+
+       public function testDebug() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setDebug( true );
+               $this->assertEquals( $derived->getDebug(), true );
+       }
+
+       public function testOnly() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
                $derived->setOnly( 'styles' );
                $this->assertEquals( $derived->getOnly(), 'styles' );
@@ -58,21 +92,35 @@ class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
                $this->assertEquals( $derived->getOnly(), null );
        }
 
-       public function testSetSkin() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testVersion() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
-               $derived->setSkin( 'override' );
-               $this->assertEquals( $derived->getSkin(), 'override' );
+               $derived->setVersion( 'hw1' );
+               $this->assertEquals( $derived->getVersion(), 'hw1' );
+       }
+
+       public function testRaw() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setRaw( true );
+               $this->assertEquals( $derived->getRaw(), true );
        }
 
        public function testGetHash() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
 
                $derived->setLanguage( 'nl' );
+               $derived->setUser( 'Example' );
                // Assert that subclass is able to clear parent class "hash" member
-               $this->assertEquals( $derived->getHash(), 'nl|fallback|||scripts|||||' );
+               $this->assertEquals( $derived->getHash(), 'nl|fallback||Example|scripts|||||' );
        }
 
+       public function testAccessors() {
+               $context = self::getContext();
+               $derived = new DerivativeResourceLoaderContext( $context );
+               $this->assertSame( $derived->getRequest(), $context->getRequest() );
+               $this->assertSame( $derived->getResourceLoader(), $context->getResourceLoader() );
+       }
 }
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php
new file mode 100644 (file)
index 0000000..1093039
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * See also:
+ * - ResourceLoaderTest::testExpandModuleNames
+ * - ResourceLoaderImageModuleTest::testContext
+ *
+ * @group Cache
+ * @covers ResourceLoaderContext
+ */
+class ResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
+       protected static function getResourceLoader() {
+               return new EmptyResourceLoader( new HashConfig( [
+                       'ResourceLoaderDebug' => false,
+                       'DefaultSkin' => 'fallback',
+                       'LanguageCode' => 'nl',
+               ] ) );
+       }
+
+       public function testEmpty() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+
+               // Request parameters
+               $this->assertEquals( [], $ctx->getModules() );
+               $this->assertEquals( 'nl', $ctx->getLanguage() );
+               $this->assertEquals( false, $ctx->getDebug() );
+               $this->assertEquals( null, $ctx->getOnly() );
+               $this->assertEquals( 'fallback', $ctx->getSkin() );
+               $this->assertEquals( null, $ctx->getUser() );
+
+               // Misc
+               $this->assertEquals( 'ltr', $ctx->getDirection() );
+               $this->assertEquals( 'nl|fallback||||||||', $ctx->getHash() );
+               $this->assertInstanceOf( User::class, $ctx->getUserObj() );
+       }
+
+       public function testDummy() {
+               $this->assertInstanceOf(
+                       ResourceLoaderContext::class,
+                       ResourceLoaderContext::newDummyContext()
+               );
+       }
+
+       public function testAccessors() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertInstanceOf( WebRequest::class, $ctx->getRequest() );
+               $this->assertInstanceOf( \Psr\Log\LoggerInterface::class, $ctx->getLogger() );
+       }
+
+       public function testTypicalRequest() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'debug' => 'false',
+                       'lang' => 'zh',
+                       'modules' => 'foo|foo.quux,baz,bar|baz.quux',
+                       'only' => 'styles',
+                       'skin' => 'fallback',
+               ] ) );
+
+               // Request parameters
+               $this->assertEquals(
+                       $ctx->getModules(),
+                       [ 'foo', 'foo.quux', 'foo.baz', 'foo.bar', 'baz.quux' ]
+               );
+               $this->assertEquals( false, $ctx->getDebug() );
+               $this->assertEquals( 'zh', $ctx->getLanguage() );
+               $this->assertEquals( 'styles', $ctx->getOnly() );
+               $this->assertEquals( 'fallback', $ctx->getSkin() );
+               $this->assertEquals( null, $ctx->getUser() );
+
+               // Misc
+               $this->assertEquals( 'ltr', $ctx->getDirection() );
+               $this->assertEquals( 'zh|fallback|||styles|||||', $ctx->getHash() );
+       }
+
+       public function testShouldInclude() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertTrue( $ctx->shouldIncludeScripts(), 'Scripts in combined' );
+               $this->assertTrue( $ctx->shouldIncludeStyles(), 'Styles in combined' );
+               $this->assertTrue( $ctx->shouldIncludeMessages(), 'Messages in combined' );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'only' => 'styles'
+               ] ) );
+               $this->assertFalse( $ctx->shouldIncludeScripts(), 'Scripts not in styles-only' );
+               $this->assertTrue( $ctx->shouldIncludeStyles(), 'Styles in styles-only' );
+               $this->assertFalse( $ctx->shouldIncludeMessages(), 'Messages not in styles-only' );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'only' => 'scripts'
+               ] ) );
+               $this->assertTrue( $ctx->shouldIncludeScripts(), 'Scripts in scripts-only' );
+               $this->assertFalse( $ctx->shouldIncludeStyles(), 'Styles not in scripts-only' );
+               $this->assertFalse( $ctx->shouldIncludeMessages(), 'Messages not in scripts-only' );
+       }
+
+       public function testGetUser() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertSame( null, $ctx->getUser() );
+               $this->assertTrue( $ctx->getUserObj()->isAnon() );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'user' => 'Example'
+               ] ) );
+               $this->assertSame( 'Example', $ctx->getUser() );
+               $this->assertEquals( 'Example', $ctx->getUserObj()->getName() );
+       }
+}
index f61540d..aeb82d1 100644 (file)
@@ -154,6 +154,49 @@ class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
                $styles = $module->getStyles( $this->getResourceLoaderContext() );
                $this->assertEquals( $expected, $styles['all'] );
        }
+
+       /**
+        * @covers ResourceLoaderContext::getImageObj
+        */
+       public function testContext() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest() );
+               $this->assertFalse( $context->getImageObj(), 'Missing image parameter' );
+
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'image' => 'example',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Missing module parameter' );
+
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'modules' => 'unknown',
+                       'image' => 'example',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Not an image module' );
+
+               $rl = new EmptyResourceLoader();
+               $rl->register( 'test', [
+                       'class' => ResourceLoaderImageModule::class,
+                       'prefix' => 'test',
+                       'images' => [ 'example' => 'example.png' ],
+               ] );
+               $context = new ResourceLoaderContext( $rl, new FauxRequest( [
+                       'modules' => 'test',
+                       'image' => 'unknown',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Unknown image' );
+
+               $rl = new EmptyResourceLoader();
+               $rl->register( 'test', [
+                       'class' => ResourceLoaderImageModule::class,
+                       'prefix' => 'test',
+                       'images' => [ 'example' => 'example.png' ],
+               ] );
+               $context = new ResourceLoaderContext( $rl, new FauxRequest( [
+                       'modules' => 'test',
+                       'image' => 'example',
+               ] ) );
+               $this->assertInstanceOf( ResourceLoaderImage::class, $context->getImageObj() );
+       }
 }
 
 class ResourceLoaderImageModuleTestable extends ResourceLoaderImageModule {
index 53c9926..9a3e222 100644 (file)
@@ -163,6 +163,12 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                                [ 'single.module', 'foobar', 'foobaz' ],
                                'single.module|foobar,foobaz',
                        ],
+                       [
+                               'Ordering',
+                               [ 'foo', 'foo.baz', 'baz.quux', 'foo.bar' ],
+                               'foo|foo.baz,bar|baz.quux',
+                               [ 'foo', 'foo.baz', 'foo.bar', 'baz.quux' ],
+                       ]
                ];
        }
 
@@ -178,8 +184,12 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
         * @dataProvider providePackedModules
         * @covers ResourceLoaderContext::expandModuleNames
         */
-       public function testexpandModuleNames( $desc, $modules, $packed ) {
-               $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
+       public function testExpandModuleNames( $desc, $modules, $packed, $unpacked = null ) {
+               $this->assertEquals(
+                       $unpacked ?: $modules,
+                       ResourceLoaderContext::expandModuleNames( $packed ),
+                       $desc
+               );
        }
 
        public static function provideAddSource() {
index a480671..0797f32 100644 (file)
                assert.deepEqual( stub.getCall( 0 ).args, [ { foo: 'bar' } ], '#saveOptions called correctly' );
        } );
 
-       QUnit.test( 'saveOptions', function ( assert ) {
+       QUnit.test( 'saveOptions without Unit Separator', function ( assert ) {
                QUnit.expect( 13 );
 
-               var api = new mw.Api();
+               var api = new mw.Api( { useUS: false } );
 
                // We need to respond to the request for token first, otherwise the other requests won't be sent
                // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
                        }
                } );
        } );
+
+       QUnit.test( 'saveOptions with Unit Separator', function ( assert ) {
+               QUnit.expect( 14 );
+
+               var api = new mw.Api( { useUS: true } );
+
+               // We need to respond to the request for token first, otherwise the other requests won't be sent
+               // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
+               api.getToken( 'options' );
+               this.server.respond(
+                       /meta=tokens&type=csrf/,
+                       [ 200, { 'Content-Type': 'application/json' },
+                               '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
+               );
+
+               api.saveOptions( {} ).done( function () {
+                       assert.ok( true, 'Request completed: empty case' );
+               } );
+               api.saveOptions( { foo: 'bar' } ).done( function () {
+                       assert.ok( true, 'Request completed: simple' );
+               } );
+               api.saveOptions( { foo: 'bar', baz: 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: two options' );
+               } );
+               api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', baz: 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: bundleable with unit separator' );
+               } );
+               api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', 'baz=baz': 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: not bundleable with unit separator' );
+               } );
+               api.saveOptions( { foo: null } ).done( function () {
+                       assert.ok( true, 'Request completed: reset an option' );
+               } );
+               api.saveOptions( { 'foo|bar=quux': null } ).done( function () {
+                       assert.ok( true, 'Request completed: reset an option, not bundleable' );
+               } );
+
+               // Requests are POST, match requestBody instead of url
+               this.server.respond( function ( request ) {
+                       switch ( request.requestBody ) {
+                               // simple
+                               case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
+                               // two options
+                               case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
+                               // bundleable with unit separator
+                               case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C':
+                               // not bundleable with unit separator
+                               case 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C':
+                               case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C':
+                               // reset an option
+                               case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
+                               // reset an option, not bundleable
+                               case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
+                                       assert.ok( true, 'Repond to ' + request.requestBody );
+                                       request.respond( 200, { 'Content-Type': 'application/json' },
+                                               '{ "options": "success" }' );
+                                       break;
+                               default:
+                                       assert.ok( false, 'Unexpected request: ' + request.requestBody );
+                       }
+               } );
+       } );
 }( mediaWiki ) );