From: jenkins-bot Date: Fri, 3 Feb 2017 06:06:26 +0000 (+0000) Subject: Merge "Avoid joining against page table when finding a page's oldest revision." X-Git-Tag: 1.31.0-rc.0~4156 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=7ebf24be75fcdaecfcdd193e5ab58e351138035e;hp=e74264c071856844a3090400219f0f63ef620cb1 Merge "Avoid joining against page table when finding a page's oldest revision." --- diff --git a/RELEASE-NOTES-1.29 b/RELEASE-NOTES-1.29 index 8fa29c1eee..c04c8f780d 100644 --- a/RELEASE-NOTES-1.29 +++ b/RELEASE-NOTES-1.29 @@ -96,6 +96,7 @@ production. no longer returns a 'message' on success. * Added action=validatepassword to validate passwords for the account creation and password change forms. +* action=purge now requires a POST. === Action API internal changes in 1.29 === * New methods were added to ApiBase to handle errors and warnings using i18n @@ -136,6 +137,7 @@ changes to languages because of Phabricator reports. The new or reinstated language fallbacks are (after cs ↔ sk in 1.28): ca ↔ oc; hsb ↔ dsb; io → eo; mdf → ru; pnt → el; roa-tara → it; rup → ro; sh → bs, sr-el, hr. +* (T155957) Talk Namespaces for Javanese language (jv) have been updated. ==== No fallback for Ukrainian ==== * (T39314) The fallback from Ukrainian to Russian was removed. The Ukrainian diff --git a/autoload.php b/autoload.php index a6840b4fb7..b871535fc5 100644 --- a/autoload.php +++ b/autoload.php @@ -506,6 +506,7 @@ $wgAutoloadLocalClasses = [ 'FormSpecialPage' => __DIR__ . '/includes/specialpage/FormSpecialPage.php', 'FormatJson' => __DIR__ . '/includes/json/FormatJson.php', 'FormatMetadata' => __DIR__ . '/includes/media/FormatMetadata.php', + 'FormattedRCFeed' => __DIR__ . '/includes/rcfeed/FormattedRCFeed.php', 'FormlessAction' => __DIR__ . '/includes/actions/FormlessAction.php', 'GIFHandler' => __DIR__ . '/includes/media/GIF.php', 'GIFMetadataExtractor' => __DIR__ . '/includes/media/GIFMetadataExtractor.php', @@ -567,6 +568,7 @@ $wgAutoloadLocalClasses = [ 'HTMLTextFieldWithButton' => __DIR__ . '/includes/htmlform/fields/HTMLTextFieldWithButton.php', 'HTMLTitleTextField' => __DIR__ . '/includes/htmlform/fields/HTMLTitleTextField.php', 'HTMLUserTextField' => __DIR__ . '/includes/htmlform/fields/HTMLUserTextField.php', + 'HTMLUsersMultiselectField' => __DIR__ . '/includes/htmlform/fields/HTMLUsersMultiselectField.php', 'HTTPFileStreamer' => __DIR__ . '/includes/libs/filebackend/HTTPFileStreamer.php', 'HWLDFWordAccumulator' => __DIR__ . '/includes/diff/DairikiDiff.php', 'HashBagOStuff' => __DIR__ . '/includes/libs/objectcache/HashBagOStuff.php', @@ -597,7 +599,6 @@ $wgAutoloadLocalClasses = [ 'IJobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php', 'ILBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/ILBFactory.php', 'ILoadBalancer' => __DIR__ . '/includes/libs/rdbms/loadbalancer/ILoadBalancer.php', - 'ILoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/ILoadMonitor.php', 'ILocalizedException' => __DIR__ . '/includes/exception/LocalizedException.php', 'IMaintainableDatabase' => __DIR__ . '/includes/libs/rdbms/database/IMaintainableDatabase.php', 'IP' => __DIR__ . '/includes/libs/IP.php', @@ -746,9 +747,6 @@ $wgAutoloadLocalClasses = [ 'ListredirectsPage' => __DIR__ . '/includes/specials/SpecialListredirects.php', 'LoadBalancer' => __DIR__ . '/includes/libs/rdbms/loadbalancer/LoadBalancer.php', 'LoadBalancerSingle' => __DIR__ . '/includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php', - 'LoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitor.php', - 'LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php', - 'LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php', 'LocalFile' => __DIR__ . '/includes/filerepo/file/LocalFile.php', 'LocalFileDeleteBatch' => __DIR__ . '/includes/filerepo/file/LocalFile.php', 'LocalFileLockError' => __DIR__ . '/includes/filerepo/file/LocalFile.php', @@ -941,6 +939,7 @@ $wgAutoloadLocalClasses = [ 'MediaWiki\\Widget\\Search\\SimpleSearchResultWidget' => __DIR__ . '/includes/widget/search/SimpleSearchResultWidget.php', 'MediaWiki\\Widget\\TitleInputWidget' => __DIR__ . '/includes/widget/TitleInputWidget.php', 'MediaWiki\\Widget\\UserInputWidget' => __DIR__ . '/includes/widget/UserInputWidget.php', + 'MediaWiki\\Widget\\UsersMultiselectWidget' => __DIR__ . '/includes/widget/UsersMultiselectWidget.php', 'MemCachedClientforWiki' => __DIR__ . '/includes/compat/MemcachedClientCompat.php', 'MemcLockManager' => __DIR__ . '/includes/libs/lockmanager/MemcLockManager.php', 'MemcachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/MemcachedBagOStuff.php', @@ -1146,6 +1145,7 @@ $wgAutoloadLocalClasses = [ 'RCCacheEntry' => __DIR__ . '/includes/changes/RCCacheEntry.php', 'RCCacheEntryFactory' => __DIR__ . '/includes/changes/RCCacheEntryFactory.php', 'RCDatabaseLogEntry' => __DIR__ . '/includes/logging/LogEntry.php', + 'RCFeed' => __DIR__ . '/includes/rcfeed/RCFeed.php', 'RCFeedEngine' => __DIR__ . '/includes/rcfeed/RCFeedEngine.php', 'RCFeedFormatter' => __DIR__ . '/includes/rcfeed/RCFeedFormatter.php', 'RESTBagOStuff' => __DIR__ . '/includes/libs/objectcache/RESTBagOStuff.php', @@ -1589,6 +1589,10 @@ $wgAutoloadLocalClasses = [ 'WikiTextStructure' => __DIR__ . '/includes/content/WikiTextStructure.php', 'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php', 'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php', + 'Wikimedia\\Rdbms\\ILoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/ILoadMonitor.php', + 'Wikimedia\\Rdbms\\LoadMonitor' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitor.php', + 'Wikimedia\\Rdbms\\LoadMonitorMySQL' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php', + 'Wikimedia\\Rdbms\\LoadMonitorNull' => __DIR__ . '/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php', 'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php', 'Wikimedia\\Rdbms\\TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php', 'WikitextContent' => __DIR__ . '/includes/content/WikitextContent.php', diff --git a/composer.json b/composer.json index 3b72bfda54..5966f4b5d2 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "ext-xml": "*", "liuggio/statsd-php-client": "1.0.18", "mediawiki/at-ease": "1.1.0", - "oojs/oojs-ui": "0.18.4", + "oojs/oojs-ui": "0.19.0", "oyejorge/less.php": "1.7.0.10", "php": ">=5.5.9", "psr/log": "1.0.0", diff --git a/docs/hooks.txt b/docs/hooks.txt index 27773f6c9b..1459b892c1 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -212,9 +212,13 @@ related to a particular event, like so: # ... function protect() { global $wgUser; - if ( Hooks::run( 'ArticleProtect', array( &$this, &$wgUser ) ) ) { + + // Avoid PHP 7.1 warning from passing $this by reference + $article = $this; + + if ( Hooks::run( 'ArticleProtect', [ &$article, &$wgUser ] ) ) { # protect the article - Hooks::run( 'ArticleProtectComplete', array( &$this, &$wgUser ) ); + Hooks::run( 'ArticleProtectComplete', [ &$article, &$wgUser ] ); } } } diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index a7cbd96dd8..c7c7fb7ac7 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -6656,51 +6656,64 @@ $wgRCLinkLimits = [ 50, 100, 250, 500 ]; $wgRCLinkDays = [ 1, 3, 7, 14, 30 ]; /** - * Destinations to which notifications about recent changes - * should be sent. - * - * As of MediaWiki 1.22, there are 2 supported 'engine' parameter option in core: - * * 'UDPRCFeedEngine', which is used to send recent changes over UDP to the - * specified server. - * * 'RedisPubSubFeedEngine', which is used to send recent changes to Redis. - * - * The common options are: - * * 'uri' -- the address to which the notices are to be sent. - * * 'formatter' -- the class name (implementing RCFeedFormatter) which will - * produce the text to send. This can also be an object of the class. - * * 'omit_bots' -- whether the bot edits should be in the feed - * * 'omit_anon' -- whether anonymous edits should be in the feed - * * 'omit_user' -- whether edits by registered users should be in the feed - * * 'omit_minor' -- whether minor edits should be in the feed - * * 'omit_patrolled' -- whether patrolled edits should be in the feed - * - * The IRC-specific options are: - * * 'add_interwiki_prefix' -- whether the titles should be prefixed with - * the first entry in the $wgLocalInterwikis array (or the value of - * $wgLocalInterwiki, if set) - * - * The JSON-specific options are: - * * 'channel' -- if set, the 'channel' parameter is also set in JSON values. + * Configuration for feeds to which notifications about recent changes will be sent. + * + * The following feed classes are available by default: + * - 'UDPRCFeedEngine' - sends recent changes over UDP to the specified server. + * - 'RedisPubSubFeedEngine' - send recent changes to Redis. + * + * Only 'class' or 'uri' is required. If 'uri' is set instead of 'class', then + * RecentChange::getEngine() is used to determine the class. All options are + * passed to the constructor. + * + * Common options: + * - 'class' -- The class to use for this feed (must implement RCFeed). + * - 'omit_bots' -- Exclude bot edits from the feed. (default: false) + * - 'omit_anon' -- Exclude anonymous edits from the feed. (default: false) + * - 'omit_user' -- Exclude edits by registered users from the feed. (default: false) + * - 'omit_minor' -- Exclude minor edits from the feed. (default: false) + * - 'omit_patrolled' -- Exclude patrolled edits from the feed. (default: false) + * + * FormattedRCFeed-specific options: + * - 'uri' -- [required] The address to which the messages are sent. + * The uri scheme of this string will be looked up in $wgRCEngines + * to determine which RCFeedEngine class to use. + * - 'formatter' -- [required] The class (implementing RCFeedFormatter) which will + * produce the text to send. This can also be an object of the class. + * Formatters available by default: JSONRCFeedFormatter, XMLRCFeedFormatter, + * IRCColourfulRCFeedFormatter. + * + * IRCColourfulRCFeedFormatter-specific options: + * - 'add_interwiki_prefix' -- whether the titles should be prefixed with + * the first entry in the $wgLocalInterwikis array (or the value of + * $wgLocalInterwiki, if set) + * + * JSONRCFeedFormatter-specific options: + * - 'channel' -- if set, the 'channel' parameter is also set in JSON values. * * @example $wgRCFeeds['example'] = [ + * 'uri' => 'udp://localhost:1336', * 'formatter' => 'JSONRCFeedFormatter', - * 'uri' => "udp://localhost:1336", * 'add_interwiki_prefix' => false, * 'omit_bots' => true, * ]; - * @example $wgRCFeeds['exampleirc'] = [ + * @example $wgRCFeeds['example'] = [ + * 'uri' => 'udp://localhost:1338', * 'formatter' => 'IRCColourfulRCFeedFormatter', - * 'uri' => "udp://localhost:1338", * 'add_interwiki_prefix' => false, * 'omit_bots' => true, * ]; + * @example $wgRCFeeds['example'] = [ + * 'class' => 'ExampleRCFeed', + * ]; * @since 1.22 */ $wgRCFeeds = []; /** - * Used by RecentChange::getEngine to find the correct engine to use for a given URI scheme. - * Keys are scheme names, values are names of engine classes. + * Used by RecentChange::getEngine to find the correct engine for a given URI scheme. + * Keys are scheme names, values are names of FormattedRCFeed sub classes. + * @since 1.22 */ $wgRCEngines = [ 'redis' => 'RedisPubSubFeedEngine', diff --git a/includes/EditPage.php b/includes/EditPage.php index 2b1bd7ba6d..34062c0621 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -3543,15 +3543,7 @@ HTML // Avoid PHP 7.1 warning of passing $this by reference $editPage = $this; if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$editPage, &$wgOut ] ) ) { - $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); - $stats->increment( 'edit.failures.conflict' ); - // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics - if ( - $this->mTitle->getNamespace() >= NS_MAIN && - $this->mTitle->getNamespace() <= NS_CATEGORY_TALK - ) { - $stats->increment( 'edit.failures.conflict.byNamespaceId.' . $this->mTitle->getNamespace() ); - } + $this->incrementConflictStats(); $wgOut->wrapWikiMsg( '

$1

', "yourdiff" ); @@ -3571,6 +3563,18 @@ HTML } } + private function incrementConflictStats() { + $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $stats->increment( 'edit.failures.conflict' ); + // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics + if ( + $this->mTitle->getNamespace() >= NS_MAIN && + $this->mTitle->getNamespace() <= NS_CATEGORY_TALK + ) { + $stats->increment( 'edit.failures.conflict.byNamespaceId.' . $this->mTitle->getNamespace() ); + } + } + /** * @return string */ @@ -3683,8 +3687,6 @@ HTML global $wgOut, $wgRawHtml, $wgLang; global $wgAllowUserCss, $wgAllowUserJs; - $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); - if ( $wgRawHtml && !$this->mTokenOk ) { // Could be an offsite preview attempt. This is very unsafe if // HTML is enabled, as it could be an attack. @@ -3697,7 +3699,7 @@ HTML $this->context->msg( 'session_fail_preview_html' )->text() . "", true, /* interface */true ); } - $stats->increment( 'edit.failures.session_loss' ); + $this->incrementEditFailureStats( 'session_loss' ); return $parsedNote; } @@ -3721,15 +3723,15 @@ HTML if ( $this->mTriedSave && !$this->mTokenOk ) { if ( $this->mTokenOkExceptSuffix ) { $note = $this->context->msg( 'token_suffix_mismatch' )->plain(); - $stats->increment( 'edit.failures.bad_token' ); + $this->incrementEditFailureStats( 'bad_token' ); } else { $note = $this->context->msg( 'session_fail_preview' )->plain(); - $stats->increment( 'edit.failures.session_loss' ); + $this->incrementEditFailureStats( 'session_loss' ); } } elseif ( $this->incompleteForm ) { $note = $this->context->msg( 'edit_form_incomplete' )->plain(); if ( $this->mTriedSave ) { - $stats->increment( 'edit.failures.incomplete_form' ); + $this->incrementEditFailureStats( 'incomplete_form' ); } } else { $note = $this->context->msg( 'previewnote' )->plain() . ' ' . $continueEditing; @@ -3817,6 +3819,11 @@ HTML return $previewhead . $previewHTML . $this->previewTextAfterContent; } + private function incrementEditFailureStats( $failureType ) { + $stats = MediaWikiServices::getInstance()->getStatsdDataFactory(); + $stats->increment( 'edit.failures.' . $failureType ); + } + /** * Get parser options for a preview * @return ParserOptions diff --git a/includes/MagicWord.php b/includes/MagicWord.php index 5968e87903..09317d7b1f 100644 --- a/includes/MagicWord.php +++ b/includes/MagicWord.php @@ -526,7 +526,7 @@ class MagicWord { $this->mFound = false; $text = preg_replace_callback( $this->getRegex(), - [ &$this, 'pregRemoveAndRecord' ], + [ $this, 'pregRemoveAndRecord' ], $text ); @@ -541,7 +541,7 @@ class MagicWord { $this->mFound = false; $text = preg_replace_callback( $this->getRegexStart(), - [ &$this, 'pregRemoveAndRecord' ], + [ $this, 'pregRemoveAndRecord' ], $text ); diff --git a/includes/api/ApiPurge.php b/includes/api/ApiPurge.php index 324d030fdb..312463835c 100644 --- a/includes/api/ApiPurge.php +++ b/includes/api/ApiPurge.php @@ -37,11 +37,6 @@ class ApiPurge extends ApiBase { * Purges the cache of a page */ public function execute() { - $main = $this->getMain(); - if ( !$main->isInternalMode() && !$main->getRequest()->wasPosted() ) { - $this->addDeprecation( 'apiwarn-deprecation-purge-get', 'purge-via-GET' ); - } - $params = $this->extractRequestParams(); $continuationManager = new ApiContinuationManager( $this, [], [] ); @@ -60,12 +55,8 @@ class ApiPurge extends ApiBase { ApiQueryBase::addTitleInfo( $r, $title ); $page = WikiPage::factory( $title ); if ( !$user->pingLimiter( 'purge' ) ) { - $flags = WikiPage::PURGE_ALL; - if ( !$this->getRequest()->wasPosted() ) { - $flags ^= WikiPage::PURGE_GLOBAL_PCACHE; // skip DB_MASTER write - } // Directly purge and skip the UI part of purge() - $page->doPurge( $flags ); + $page->doPurge( WikiPage::PURGE_ALL ); $r['purged'] = true; } else { $this->addWarning( 'apierror-ratelimited' ); @@ -157,20 +148,7 @@ class ApiPurge extends ApiBase { } public function mustBePosted() { - // Anonymous users are not allowed a non-POST request - return !$this->getUser()->isAllowed( 'purge' ); - } - - protected function getHelpFlags() { - $flags = parent::getHelpFlags(); - - // Claim that we must be posted for the purposes of help and paraminfo. - // @todo Remove this when self::mustBePosted() is updated for T145649 - if ( !in_array( 'mustbeposted', $flags, true ) ) { - $flags[] = 'mustbeposted'; - } - - return $flags; + return true; } public function getAllowedParams( $flags = 0 ) { diff --git a/includes/api/ApiQueryAllUsers.php b/includes/api/ApiQueryAllUsers.php index 1c3b171fd4..136f60ecce 100644 --- a/includes/api/ApiQueryAllUsers.php +++ b/includes/api/ApiQueryAllUsers.php @@ -147,7 +147,9 @@ class ApiQueryAllUsers extends ApiQueryBase { $this->addJoinConds( [ 'ug1' => [ 'LEFT OUTER JOIN', array_merge( [ 'ug1.ug_user=user_id', - 'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() ) + $this->getConfig()->get( 'DisableUserGroupExpiry' ) ? + '1' : + 'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() ) ], $exclude ) ] ] ); $this->addWhere( 'ug1.ug_user IS NULL' ); @@ -163,7 +165,9 @@ class ApiQueryAllUsers extends ApiQueryBase { $this->addFields( [ 'groups' => $db->buildGroupConcatField( '|', 'user_groups', 'ug_group', [ 'ug_user=user_id', - 'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() ) + $this->getConfig()->get( 'DisableUserGroupExpiry' ) ? + '1' : + 'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() ) ] ) ] ); } diff --git a/includes/api/i18n/nl.json b/includes/api/i18n/nl.json index decd400acf..de9f1a415c 100644 --- a/includes/api/i18n/nl.json +++ b/includes/api/i18n/nl.json @@ -151,6 +151,7 @@ "apihelp-help-example-recursive": "Alle hulp op een pagina.", "apihelp-help-example-help": "Help voor de help-module zelf.", "apihelp-imagerotate-description": "Een of meerdere afbeeldingen draaien.", + "apihelp-imagerotate-param-rotation": "Aantal graden om de afbeelding met de klok mee te draaien.", "apihelp-imagerotate-param-tags": "Labels om toe te voegen aan de regel in het uploadlogboek.", "apihelp-imagerotate-example-simple": "Roteer File:Example.png met 90 graden.", "apihelp-imagerotate-example-generator": "Roteer alle afbeeldingen in Category:Flip met 180 graden.", @@ -160,6 +161,7 @@ "apihelp-import-param-interwikisource": "Voor interwiki imports: wiki om van te importeren.", "apihelp-import-param-namespace": "Importeren in deze naamruimte. Can niet samen gebruikt worden met $1rootpage.", "apihelp-import-param-rootpage": "Importeren als subpagina van deze pagina. Kan niet samen met $1namespace gebruikt worden.", + "apihelp-import-example-import": "Importeer [[meta:Help:ParserFunctions]] in naamruimte 100 met de volledige geschiedenis.", "apihelp-login-param-name": "Gebruikersnaam.", "apihelp-login-param-password": "Wachtwoord.", "apihelp-login-param-domain": "Domein (optioneel).", @@ -168,6 +170,7 @@ "apihelp-logout-example-logout": "Meldt de huidige gebruiker af.", "apihelp-managetags-param-tag": "Label om aan te maken, te activeren of te deactiveren. Voor het aanmaken van een label, mag het niet bestaan. Voor het verwijderen van een label, moet het bestaan. Voor het activeren van een label, moet het bestaan en mag het niet gebruikt worden door een uitbreiding. Voor het deactiveren van een label, moet het gebruikt worden en handmatig gedefinieerd zijn.", "apihelp-managetags-example-create": "Maak een label met de naam spam aan met als reden For use in edit patrolling", + "apihelp-managetags-example-delete": "Verwijder het vandlaism label met de reden Misspelt", "apihelp-move-description": "Pagina hernoemen.", "apihelp-move-param-to": "Nieuwe paginanaam.", "apihelp-move-param-reason": "Reden voor de naamswijziging.", @@ -195,6 +198,7 @@ "apihelp-options-param-optionvalue": "De waarde voor de optie opgegeven door $1optionname.", "apihelp-options-example-reset": "Alle voorkeuren opnieuw instellen.", "apihelp-options-example-change": "Voorkeuren wijzigen voor skin en hideminor.", + "apihelp-paraminfo-description": "Verkrijg informatie over API-modules.", "apihelp-parse-paramvalue-prop-categorieshtml": "Vraagt een HTML-versie van de categorieën op.", "apihelp-parse-example-page": "Een pagina verwerken.", "apihelp-parse-example-text": "Wikitext verwerken.", @@ -204,12 +208,17 @@ "apihelp-patrol-example-revid": "Een versie markeren als gecontroleerd.", "apihelp-protect-param-reason": "Reden voor opheffen van de beveiliging.", "apihelp-protect-example-protect": "Een pagina beveiligen", + "apihelp-purge-param-forcelinkupdate": "Werk de koppelingstabellen bij.", + "apihelp-purge-param-forcerecursivelinkupdate": "Werk de koppelingentabel bij, en werk de koppelingstabellen bij voor alle pagina's die gebruik maken van deze pagina als sjabloon.", "apihelp-query+allcategories-param-dir": "Richting om in te sorteren.", "apihelp-query+allcategories-paramvalue-prop-size": "Voegt het aantal pagina's in de categorie toe.", "apihelp-query+allcategories-paramvalue-prop-hidden": "Markeert categorieën die verborgen zijn met __HIDDENCAT__", "apihelp-query+alldeletedrevisions-param-tag": "Alleen versies weergeven met dit label.", "apihelp-query+alldeletedrevisions-param-excludeuser": "Toon geen versies door deze gebruiker.", "apihelp-query+alldeletedrevisions-param-namespace": "Toon alleen pagina's in deze naamruimte.", + "apihelp-query+allfileusages-paramvalue-prop-title": "Voegt de titel van het bestand toe.", + "apihelp-query+allfileusages-param-limit": "Hoeveel items er in totaal moeten worden getoond.", + "apihelp-query+allimages-example-recent": "Toon een lijst van recentlijk geüploade bestanden, vergelijkbaar met [[Special:NewFiles]].", "apihelp-query+alllinks-param-namespace": "De naamruimte om door te lopen.", "apihelp-query+alllinks-param-limit": "Hoeveel items er in totaal moeten worden getoond.", "apihelp-query+allmessages-param-enableparser": "Stel in om de parser in te schakelen, zorgt voor het voorverwerken van de wikitekst van een bericht (vervangen van magische woorden, de afhandeling van sjablonen, enzovoort).", diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php index 9bf0840eeb..4facc20af5 100644 --- a/includes/cache/MessageCache.php +++ b/includes/cache/MessageCache.php @@ -584,7 +584,8 @@ class MessageCache { return; } // Load the messages from the master DB to avoid race conditions - $this->loadFromDB( $code, self::FOR_UPDATE ); + $cache = $this->loadFromDB( $code, self::FOR_UPDATE ); + $this->mCache[$code] = $cache; // Load the process cache values and set the per-title cache keys $page = WikiPage::factory( Title::makeTitle( NS_MEDIAWIKI, $title ) ); $page->loadPageData( $page::READ_LATEST ); diff --git a/includes/changes/ChangesList.php b/includes/changes/ChangesList.php index 77038edd7d..1e88e13636 100644 --- a/includes/changes/ChangesList.php +++ b/includes/changes/ChangesList.php @@ -444,8 +444,10 @@ class ChangesList extends ContextSource { # TODO: Deprecate the $s argument, it seems happily unused. $s = ''; + # Avoid PHP 7.1 warning from passing $this by reference + $changesList = $this; Hooks::run( 'ChangesListInsertArticleLink', - [ &$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched ] ); + [ &$changesList, &$articlelink, &$s, &$rc, $unpatrolled, $watched ] ); return "{$s} {$articlelink}"; } diff --git a/includes/changes/OldChangesList.php b/includes/changes/OldChangesList.php index 8eb06ced03..d862ef482f 100644 --- a/includes/changes/OldChangesList.php +++ b/includes/changes/OldChangesList.php @@ -50,7 +50,9 @@ class OldChangesList extends ChangesList { $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] ); } - if ( !Hooks::run( 'OldChangesListRecentChangesLine', [ &$this, &$html, $rc, &$classes ] ) ) { + // Avoid PHP 7.1 warning from passing $this by reference + $list = $this; + if ( !Hooks::run( 'OldChangesListRecentChangesLine', [ &$list, &$html, $rc, &$classes ] ) ) { return false; } diff --git a/includes/changes/RecentChange.php b/includes/changes/RecentChange.php index 13a5fc7b80..507e6c3646 100644 --- a/includes/changes/RecentChange.php +++ b/includes/changes/RecentChange.php @@ -329,7 +329,9 @@ class RecentChange { $this->mAttribs['rc_id'] = $dbw->insertId(); # Notify extensions - Hooks::run( 'RecentChange_save', [ &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $rc = $this; + Hooks::run( 'RecentChange_save', [ &$rc ] ); if ( count( $this->tags ) ) { ChangeTags::addTags( $this->tags, $this->mAttribs['rc_id'], @@ -389,8 +391,8 @@ class RecentChange { $performer = $this->getPerformer(); - foreach ( $feeds as $feed ) { - $feed += [ + foreach ( $feeds as $params ) { + $params += [ 'omit_bots' => false, 'omit_anon' => false, 'omit_user' => false, @@ -399,58 +401,44 @@ class RecentChange { ]; if ( - ( $feed['omit_bots'] && $this->mAttribs['rc_bot'] ) || - ( $feed['omit_anon'] && $performer->isAnon() ) || - ( $feed['omit_user'] && !$performer->isAnon() ) || - ( $feed['omit_minor'] && $this->mAttribs['rc_minor'] ) || - ( $feed['omit_patrolled'] && $this->mAttribs['rc_patrolled'] ) || + ( $params['omit_bots'] && $this->mAttribs['rc_bot'] ) || + ( $params['omit_anon'] && $performer->isAnon() ) || + ( $params['omit_user'] && !$performer->isAnon() ) || + ( $params['omit_minor'] && $this->mAttribs['rc_minor'] ) || + ( $params['omit_patrolled'] && $this->mAttribs['rc_patrolled'] ) || $this->mAttribs['rc_type'] == RC_EXTERNAL ) { continue; } - $engine = self::getEngine( $feed['uri'] ); - if ( isset( $this->mExtra['actionCommentIRC'] ) ) { $actionComment = $this->mExtra['actionCommentIRC']; } else { $actionComment = null; } - /** @var $formatter RCFeedFormatter */ - $formatter = is_object( $feed['formatter'] ) ? $feed['formatter'] : new $feed['formatter'](); - $line = $formatter->getLine( $feed, $this, $actionComment ); - if ( !$line ) { - // T109544 - // If a feed formatter returns null, this will otherwise cause an - // error in at least RedisPubSubFeedEngine. - // Not sure where/how this should best be handled. - continue; - } - - $engine->send( $feed, $line ); + $feed = RCFeed::factory( $params ); + $feed->notify( $this, $actionComment ); } } /** - * Gets the stream engine object for a given URI from $wgRCEngines - * + * @since 1.22 + * @deprecated since 1.29 Use RCFeed::factory() instead * @param string $uri URI to get the engine object for - * @throws MWException * @return RCFeedEngine The engine object + * @throws MWException */ public static function getEngine( $uri ) { + // TODO: Merge into RCFeed::factory(). global $wgRCEngines; - $scheme = parse_url( $uri, PHP_URL_SCHEME ); if ( !$scheme ) { - throw new MWException( __FUNCTION__ . ": Invalid stream logger URI: '$uri'" ); + throw new MWException( "Invalid RCFeed uri: '$uri'" ); } - if ( !isset( $wgRCEngines[$scheme] ) ) { - throw new MWException( __FUNCTION__ . ": Unknown stream logger URI scheme: $scheme" ); + throw new MWException( "Unknown RCFeedEngine scheme: '$scheme'" ); } - if ( defined( 'MW_PHPUNIT_TEST' ) && is_object( $wgRCEngines[$scheme] ) ) { return $wgRCEngines[$scheme]; } diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index c3502f60ad..d8ed7a949c 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -668,7 +668,7 @@ class DatabaseOracle extends Database { list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) = $this->makeSelectOptions( $selectOptions ); if ( is_array( $srcTable ) ) { - $srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) ); + $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) ); } else { $srcTable = $this->tableName( $srcTable ); } @@ -998,7 +998,7 @@ class DatabaseOracle extends Database { private function fieldInfoMulti( $table, $field ) { $field = strtoupper( $field ); if ( is_array( $table ) ) { - $table = array_map( [ &$this, 'tableNameInternal' ], $table ); + $table = array_map( [ $this, 'tableNameInternal' ], $table ); $tableWhere = 'IN ('; foreach ( $table as &$singleTable ) { $singleTable = $this->removeIdentifierQuotes( $singleTable ); diff --git a/includes/deferred/LinksUpdate.php b/includes/deferred/LinksUpdate.php index 229a9a258f..464c908b40 100644 --- a/includes/deferred/LinksUpdate.php +++ b/includes/deferred/LinksUpdate.php @@ -154,7 +154,9 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate { $this->mRecursive = $recursive; - Hooks::run( 'LinksUpdateConstructed', [ &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $linksUpdate = $this; + Hooks::run( 'LinksUpdateConstructed', [ &$linksUpdate ] ); } /** @@ -169,7 +171,9 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate { $scopedLock = self::acquirePageLock( $this->getDB(), $this->mId ); } - Hooks::run( 'LinksUpdate', [ &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $linksUpdate = $this; + Hooks::run( 'LinksUpdate', [ &$linksUpdate ] ); $this->doIncrementalUpdate(); // Commit and release the lock (if set) @@ -177,7 +181,9 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate { // Run post-commit hooks without DBO_TRX $this->getDB()->onTransactionIdle( function () { - Hooks::run( 'LinksUpdateComplete', [ &$this, $this->ticket ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $linksUpdate = $this; + Hooks::run( 'LinksUpdateComplete', [ &$linksUpdate, $this->ticket ] ); }, __METHOD__ ); diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index 559a5ec667..5367199f2f 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -762,8 +762,11 @@ class DifferenceEngine extends ContextSource { $difftext = $this->generateContentDiffBody( $this->mOldContent, $this->mNewContent ); + // Avoid PHP 7.1 warning from passing $this by reference + $diffEngine = $this; + // Save to cache for 7 days - if ( !Hooks::run( 'AbortDiffCache', [ &$this ] ) ) { + if ( !Hooks::run( 'AbortDiffCache', [ &$diffEngine ] ) ) { wfIncrStats( 'diff_cache.uncacheable' ); } elseif ( $key !== false && $difftext !== false ) { wfIncrStats( 'diff_cache.miss' ); @@ -982,7 +985,7 @@ class DifferenceEngine extends ContextSource { public function localiseLineNumbers( $text ) { return preg_replace_callback( '//', - [ &$this, 'localiseLineNumbersCb' ], + [ $this, 'localiseLineNumbersCb' ], $text ); } diff --git a/includes/export/XmlDumpWriter.php b/includes/export/XmlDumpWriter.php index 5be166b29d..52bf0f0910 100644 --- a/includes/export/XmlDumpWriter.php +++ b/includes/export/XmlDumpWriter.php @@ -269,7 +269,9 @@ class XmlDumpWriter { $out .= " \n"; } - Hooks::run( 'XmlDumpWriterWriteRevision', [ &$this, &$out, $row, $text ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $writer = $this; + Hooks::run( 'XmlDumpWriterWriteRevision', [ &$writer, &$out, $row, $text ] ); $out .= " \n"; diff --git a/includes/filerepo/file/LocalFile.php b/includes/filerepo/file/LocalFile.php index be0751ff9a..8c088b9221 100644 --- a/includes/filerepo/file/LocalFile.php +++ b/includes/filerepo/file/LocalFile.php @@ -1070,7 +1070,9 @@ class LocalFile extends File { $opts['ORDER BY'] = "oi_timestamp $order"; $opts['USE INDEX'] = [ 'oldimage' => 'oi_name_timestamp' ]; - Hooks::run( 'LocalFile::getHistory', [ &$this, &$tables, &$fields, + // Avoid PHP 7.1 warning from passing $this by reference + $localFile = $this; + Hooks::run( 'LocalFile::getHistory', [ &$localFile, &$tables, &$fields, &$conds, &$opts, &$join_conds ] ); $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $opts, $join_conds ); diff --git a/includes/htmlform/HTMLForm.php b/includes/htmlform/HTMLForm.php index e627cfdc69..179f6af776 100644 --- a/includes/htmlform/HTMLForm.php +++ b/includes/htmlform/HTMLForm.php @@ -165,6 +165,7 @@ class HTMLForm extends ContextSource { 'url' => 'HTMLTextField', 'title' => 'HTMLTitleTextField', 'user' => 'HTMLUserTextField', + 'usersmultiselect' => 'HTMLUsersMultiselectField', ]; public $mFieldData; diff --git a/includes/htmlform/fields/HTMLUsersMultiselectField.php b/includes/htmlform/fields/HTMLUsersMultiselectField.php new file mode 100644 index 0000000000..8c1241d015 --- /dev/null +++ b/includes/htmlform/fields/HTMLUsersMultiselectField.php @@ -0,0 +1,86 @@ +getCheck( $this->mName ) ) { + return $this->getDefault(); + } + + $usersArray = explode( "\n", $request->getText( $this->mName ) ); + // Remove empty lines + $usersArray = array_values( array_filter( $usersArray, function( $username ) { + return trim( $username ) !== ''; + } ) ); + return $usersArray; + } + + public function validate( $value, $alldata ) { + if ( !$this->mParams['exists'] ) { + return true; + } + + if ( is_null( $value ) ) { + return false; + } + + foreach ( $value as $username ) { + $result = parent::validate( $username, $alldata ); + if ( $result !== true ) { + return $result; + } + } + + return true; + } + + public function getInputHTML( $values ) { + $this->mParent->getOutput()->enableOOUI(); + return $this->getInputOOUI( $values ); + } + + public function getInputOOUI( $values ) { + $params = [ 'name' => $this->mName ]; + + if ( isset( $this->mParams['default'] ) ) { + $params['default'] = $this->mParams['default']; + } + + if ( isset( $this->mParams['placeholder'] ) ) { + $params['placeholder'] = $this->mParams['placeholder']; + } else { + $params['placeholder'] = $this->msg( 'mw-widgets-usersmultiselect-placeholder' ) + ->inContentLanguage() + ->plain(); + } + + if ( !is_null( $values ) ) { + $params['default'] = $values; + } + + return new UsersMultiselectWidget( $params ); + } + + protected function shouldInfuseOOUI() { + return true; + } + + protected function getOOUIModules() { + return [ 'mediawiki.widgets.UsersMultiselectWidget' ]; + } + +} diff --git a/includes/installer/MysqlUpdater.php b/includes/installer/MysqlUpdater.php index 7a27f5f2eb..9be6c3d65c 100644 --- a/includes/installer/MysqlUpdater.php +++ b/includes/installer/MysqlUpdater.php @@ -294,6 +294,7 @@ class MysqlUpdater extends DatabaseUpdater { // 1.29 [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ], + [ 'dropIndex', 'user_groups', 'ug_user_group', 'patch-user_groups-primary-key.sql' ], [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ], ]; } diff --git a/includes/installer/i18n/uk.json b/includes/installer/i18n/uk.json index 7644f417ab..78730351b6 100644 --- a/includes/installer/i18n/uk.json +++ b/includes/installer/i18n/uk.json @@ -308,6 +308,7 @@ "config-install-subscribe-fail": "Не можливо підписатись на mediawiki-announce: $1", "config-install-subscribe-notpossible": "cURL не встановлено і опція allow_url_fopen не доступна.", "config-install-mainpage": "Створення головної сторінки із вмістом за замовчуванням", + "config-install-mainpage-exists": "Головна сторінка вже існує, пропускаємо", "config-install-extension-tables": "Створення таблиць для увімкнених розширень", "config-install-mainpage-failed": "Не вдається вставити головну сторінку: $1", "config-install-done": "Вітаємо!\nВи успішно встановили MediaWiki.\n\nІнсталятор згенерував файл LocalSettings.php, який містить усі Ваші налаштування.\n\nВам необхідно завантажити його і помістити у кореневу папку Вашої вікі (туди ж, де index.php). Завантаження мало початись автоматично.\n\nЯкщо завантаження не почалось або Ви його скасували, можете заново його почати, натиснувши на посилання внизу:\n\n$3\n\nПримітка: Якщо Ви не зробите цього зараз, цей файл не буде доступним пізніше, коли Ви вийдете з встановлення, не скачавши його.\n\nПісля виконання дій, описаних вище, Ви зможете [$2 увійти у свою вікі].", diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index 68d500ba6c..d15d6f1937 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -2314,7 +2314,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $selectOptions ); if ( is_array( $srcTable ) ) { - $srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) ); + $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) ); } else { $srcTable = $this->tableName( $srcTable ); } diff --git a/includes/libs/rdbms/database/DatabasePostgres.php b/includes/libs/rdbms/database/DatabasePostgres.php index 42113b0851..75cc97c9d5 100644 --- a/includes/libs/rdbms/database/DatabasePostgres.php +++ b/includes/libs/rdbms/database/DatabasePostgres.php @@ -698,7 +698,7 @@ __INDEXATTR__; list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) = $this->makeSelectOptions( $selectOptions ); if ( is_array( $srcTable ) ) { - $srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) ); + $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) ); } else { $srcTable = $this->tableName( $srcTable ); } @@ -1257,7 +1257,7 @@ SQL; if ( isset( $options['FOR UPDATE'] ) ) { $postLimitTail .= ' FOR UPDATE OF ' . - implode( ', ', array_map( [ &$this, 'tableName' ], $options['FOR UPDATE'] ) ); + implode( ', ', array_map( [ $this, 'tableName' ], $options['FOR UPDATE'] ) ); } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) { $postLimitTail .= ' FOR UPDATE'; } diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index 78f905c76b..baac3d00f8 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -21,8 +21,10 @@ * @ingroup Database */ use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Wikimedia\ScopedCallback; use Wikimedia\Rdbms\TransactionProfiler; +use Wikimedia\Rdbms\ILoadMonitor; /** * Database connection, tracking, load balancing, and transaction manager for a cluster @@ -195,7 +197,7 @@ class LoadBalancer implements ILoadBalancer { }; foreach ( [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ] as $key ) { - $this->$key = isset( $params[$key] ) ? $params[$key] : new \Psr\Log\NullLogger(); + $this->$key = isset( $params[$key] ) ? $params[$key] : new NullLogger(); } $this->host = isset( $params['hostname'] ) @@ -212,7 +214,17 @@ class LoadBalancer implements ILoadBalancer { */ private function getLoadMonitor() { if ( !isset( $this->loadMonitor ) ) { + $compat = [ + 'LoadMonitor' => Wikimedia\Rdbms\LoadMonitor::class, + 'LoadMonitorNull' => Wikimedia\Rdbms\LoadMonitorNull::class, + 'LoadMonitorMySQL' => Wikimedia\Rdbms\LoadMonitorMySQL::class, + ]; + $class = $this->loadMonitorConfig['class']; + if ( isset( $compat[$class] ) ) { + $class = $compat[$class]; + } + $this->loadMonitor = new $class( $this, $this->srvCache, $this->memCache, $this->loadMonitorConfig ); $this->loadMonitor->setLogger( $this->replLogger ); @@ -1472,8 +1484,9 @@ class LoadBalancer implements ILoadBalancer { /** * @param IDatabase $conn - * @param DBMasterPos|false $pos + * @param DBMasterPos|bool $pos * @param int $timeout + * @return bool */ public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) { if ( $this->getServerCount() <= 1 || !$conn->getLBInfo( 'replica' ) ) { diff --git a/includes/libs/rdbms/loadmonitor/ILoadMonitor.php b/includes/libs/rdbms/loadmonitor/ILoadMonitor.php index 14a52c5a8c..38097fc87b 100644 --- a/includes/libs/rdbms/loadmonitor/ILoadMonitor.php +++ b/includes/libs/rdbms/loadmonitor/ILoadMonitor.php @@ -20,7 +20,12 @@ * @file * @ingroup Database */ + +namespace Wikimedia\Rdbms; + use Psr\Log\LoggerAwareInterface; +use BagOStuff; +use ILoadBalancer; /** * An interface for database load monitoring diff --git a/includes/libs/rdbms/loadmonitor/LoadMonitor.php b/includes/libs/rdbms/loadmonitor/LoadMonitor.php index da4909d77f..f1a6d07ccb 100644 --- a/includes/libs/rdbms/loadmonitor/LoadMonitor.php +++ b/includes/libs/rdbms/loadmonitor/LoadMonitor.php @@ -19,8 +19,14 @@ * @ingroup Database */ +namespace Wikimedia\Rdbms; + use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Wikimedia\ScopedCallback; +use ILoadBalancer; +use IDatabase; +use BagOStuff; /** * Basic DB load monitor with no external dependencies @@ -49,7 +55,7 @@ class LoadMonitor implements ILoadMonitor { $this->parent = $lb; $this->srvCache = $srvCache; $this->mainCache = $cache; - $this->replLogger = new \Psr\Log\NullLogger(); + $this->replLogger = new NullLogger(); $this->movingAveRatio = isset( $options['movingAveRatio'] ) ? $options['movingAveRatio'] diff --git a/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php b/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php index e3747943c1..afb3a23662 100644 --- a/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php +++ b/includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php @@ -19,6 +19,12 @@ * @ingroup Database */ +namespace Wikimedia\Rdbms; + +use ILoadBalancer; +use IDatabase; +use BagOStuff; + /** * Basic MySQL load monitor with no external dependencies * Uses memcached to cache the replication lag for a short time diff --git a/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php b/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php index c4e25dc24a..0a84e333b8 100644 --- a/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php +++ b/includes/libs/rdbms/loadmonitor/LoadMonitorNull.php @@ -18,7 +18,12 @@ * @file * @ingroup Database */ + +namespace Wikimedia\Rdbms; + use Psr\Log\LoggerInterface; +use ILoadBalancer; +use BagOStuff; class LoadMonitorNull implements ILoadMonitor { public function __construct( diff --git a/includes/libs/replacers/Replacer.php b/includes/libs/replacers/Replacer.php index 3b978357ed..655e771087 100644 --- a/includes/libs/replacers/Replacer.php +++ b/includes/libs/replacers/Replacer.php @@ -27,7 +27,7 @@ abstract class Replacer { * @return array */ public function cb() { - return [ &$this, 'replace' ]; + return [ $this, 'replace' ]; } /** diff --git a/includes/page/ImagePage.php b/includes/page/ImagePage.php index b60b0108a1..c75cfdd26d 100644 --- a/includes/page/ImagePage.php +++ b/includes/page/ImagePage.php @@ -336,7 +336,7 @@ class ImagePage extends Article { $filename = wfEscapeWikiText( $this->displayImg->getName() ); $linktext = $filename; - // Use of &$this in hooks triggers warnings in PHP 7.1 + // Avoid PHP 7.1 warning from passing $this by reference $imagePage = $this; Hooks::run( 'ImageOpenShowImageInlineBefore', [ &$imagePage, &$out ] ); diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index d9f6f6376e..bc936abc45 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -323,7 +323,7 @@ class WikiPage implements Page, IDBAccessObject { $row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__, $options ); - Hooks::run( 'ArticlePageDataAfter', [ &$this, &$row ] ); + Hooks::run( 'ArticlePageDataAfter', [ &$wikiPage, &$row ] ); return $row; } diff --git a/includes/parser/DateFormatter.php b/includes/parser/DateFormatter.php index 08e3c77158..76ee525cb9 100644 --- a/includes/parser/DateFormatter.php +++ b/includes/parser/DateFormatter.php @@ -197,7 +197,7 @@ class DateFormatter { // Another horrible hack $this->mLinked = $linked; - $text = preg_replace_callback( $regex, [ &$this, 'replace' ], $text ); + $text = preg_replace_callback( $regex, [ $this, 'replace' ], $text ); unset( $this->mLinked ); } return $text; diff --git a/includes/parser/LinkHolderArray.php b/includes/parser/LinkHolderArray.php index e7712f2b74..d2a0a1a6d4 100644 --- a/includes/parser/LinkHolderArray.php +++ b/includes/parser/LinkHolderArray.php @@ -613,7 +613,7 @@ class LinkHolderArray { public function replaceText( $text ) { $text = preg_replace_callback( '//', - [ &$this, 'replaceTextCallback' ], + [ $this, 'replaceTextCallback' ], $text ); return $text; diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 3ec059632e..1d55c980a1 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -330,7 +330,9 @@ class Parser { CoreTagHooks::register( $this ); $this->initialiseVariables(); - Hooks::run( 'ParserFirstCallInit', [ &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'ParserFirstCallInit', [ &$parser ] ); } /** @@ -381,7 +383,9 @@ class Parser { $this->mProfiler = new SectionProfiler(); - Hooks::run( 'ParserClearState', [ &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'ParserClearState', [ &$parser ] ); } /** @@ -435,11 +439,13 @@ class Parser { $this->mRevisionSize = null; } - Hooks::run( 'ParserBeforeStrip', [ &$this, &$text, &$this->mStripState ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'ParserBeforeStrip', [ &$parser, &$text, &$this->mStripState ] ); # No more strip! - Hooks::run( 'ParserAfterStrip', [ &$this, &$text, &$this->mStripState ] ); + Hooks::run( 'ParserAfterStrip', [ &$parser, &$text, &$this->mStripState ] ); $text = $this->internalParse( $text ); - Hooks::run( 'ParserAfterParse', [ &$this, &$text, &$this->mStripState ] ); + Hooks::run( 'ParserAfterParse', [ &$parser, &$text, &$this->mStripState ] ); $text = $this->internalParseHalfParsed( $text, true, $linestart ); @@ -615,8 +621,10 @@ class Parser { * @return string UNSAFE half-parsed HTML */ public function recursiveTagParse( $text, $frame = false ) { - Hooks::run( 'ParserBeforeStrip', [ &$this, &$text, &$this->mStripState ] ); - Hooks::run( 'ParserAfterStrip', [ &$this, &$text, &$this->mStripState ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'ParserBeforeStrip', [ &$parser, &$text, &$this->mStripState ] ); + Hooks::run( 'ParserAfterStrip', [ &$parser, &$text, &$this->mStripState ] ); $text = $this->internalParse( $text, false, $frame ); return $text; } @@ -663,8 +671,10 @@ class Parser { if ( $revid !== null ) { $this->mRevisionId = $revid; } - Hooks::run( 'ParserBeforeStrip', [ &$this, &$text, &$this->mStripState ] ); - Hooks::run( 'ParserAfterStrip', [ &$this, &$text, &$this->mStripState ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'ParserBeforeStrip', [ &$parser, &$text, &$this->mStripState ] ); + Hooks::run( 'ParserAfterStrip', [ &$parser, &$text, &$this->mStripState ] ); $text = $this->replaceVariables( $text, $frame ); $text = $this->mStripState->unstripBoth( $text ); return $text; @@ -1259,8 +1269,11 @@ class Parser { $origText = $text; + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + # Hook to suspend the parser in this state - if ( !Hooks::run( 'ParserBeforeInternalParse', [ &$this, &$text, &$this->mStripState ] ) ) { + if ( !Hooks::run( 'ParserBeforeInternalParse', [ &$parser, &$text, &$this->mStripState ] ) ) { return $text; } @@ -1280,16 +1293,16 @@ class Parser { $text = $this->replaceVariables( $text ); } - Hooks::run( 'InternalParseBeforeSanitize', [ &$this, &$text, &$this->mStripState ] ); + Hooks::run( 'InternalParseBeforeSanitize', [ &$parser, &$text, &$this->mStripState ] ); $text = Sanitizer::removeHTMLtags( $text, - [ &$this, 'attributeStripCallback' ], + [ $this, 'attributeStripCallback' ], false, array_keys( $this->mTransparentTagHooks ), [], - [ &$this, 'addTrackingCategory' ] + [ $this, 'addTrackingCategory' ] ); - Hooks::run( 'InternalParseBeforeLinks', [ &$this, &$text, &$this->mStripState ] ); + Hooks::run( 'InternalParseBeforeLinks', [ &$parser, &$text, &$this->mStripState ] ); # Tables need to come after variable replacement for things to work # properly; putting them before other transformations should keep @@ -1328,8 +1341,11 @@ class Parser { private function internalParseHalfParsed( $text, $isMain = true, $linestart = true ) { $text = $this->mStripState->unstripGeneral( $text ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + if ( $isMain ) { - Hooks::run( 'ParserAfterUnstrip', [ &$this, &$text ] ); + Hooks::run( 'ParserAfterUnstrip', [ &$parser, &$text ] ); } # Clean up special characters, only run once, next-to-last before doBlockLevels @@ -1368,7 +1384,7 @@ class Parser { $text = $this->mStripState->unstripNoWiki( $text ); if ( $isMain ) { - Hooks::run( 'ParserBeforeTidy', [ &$this, &$text ] ); + Hooks::run( 'ParserBeforeTidy', [ &$parser, &$text ] ); } $text = $this->replaceTransparentTags( $text ); @@ -1409,7 +1425,7 @@ class Parser { } if ( $isMain ) { - Hooks::run( 'ParserAfterTidy', [ &$this, &$text ] ); + Hooks::run( 'ParserAfterTidy', [ &$parser, &$text ] ); } return $text; @@ -1447,7 +1463,7 @@ class Parser { (?: [0-9] $spdash? ){9} # 9 digits with opt. delimiters [0-9Xx] # check digit )\b - )!xu", [ &$this, 'magicLinkCallback' ], $text ); + )!xu", [ $this, 'magicLinkCallback' ], $text ); return $text; } @@ -2486,18 +2502,21 @@ class Parser { . ' called while parsing (no title set)' ); } + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + /** * Some of these require message or data lookups and can be * expensive to check many times. */ - if ( Hooks::run( 'ParserGetVariableValueVarCache', [ &$this, &$this->mVarCache ] ) ) { + if ( Hooks::run( 'ParserGetVariableValueVarCache', [ &$parser, &$this->mVarCache ] ) ) { if ( isset( $this->mVarCache[$index] ) ) { return $this->mVarCache[$index]; } } $ts = wfTimestamp( TS_UNIX, $this->mOptions->getTimestamp() ); - Hooks::run( 'ParserGetVariableValueTs', [ &$this, &$ts ] ); + Hooks::run( 'ParserGetVariableValueTs', [ &$parser, &$ts ] ); $pageLang = $this->getFunctionLang(); @@ -2810,7 +2829,7 @@ class Parser { $ret = null; Hooks::run( 'ParserGetVariableValueSwitch', - [ &$this, &$this->mVarCache, &$index, &$ret, &$frame ] + [ &$parser, &$this->mVarCache, &$index, &$ret, &$frame ] ); return $ret; @@ -3354,7 +3373,10 @@ class Parser { throw new MWException( "Tag hook for $function is not callable\n" ); } - $allArgs = [ &$this ]; + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + + $allArgs = [ &$parser ]; if ( $flags & self::SFH_OBJECT_ARGS ) { # Convert arguments to PPNodes and collect for appending to $allArgs $funcArgs = []; @@ -3863,7 +3885,9 @@ class Parser { throw new MWException( "Tag hook for $name is not callable\n" ); } - $output = call_user_func_array( $callback, [ &$this, $frame, $content, $attributes ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + $output = call_user_func_array( $callback, [ &$parser, $frame, $content, $attributes ] ); } else { $output = 'Invalid tag extension name: ' . htmlspecialchars( $name ) . ''; @@ -4966,7 +4990,9 @@ class Parser { } $ig->setAdditionalOptions( $params ); - Hooks::run( 'BeforeParserrenderImageGallery', [ &$this, &$ig ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $parser = $this; + Hooks::run( 'BeforeParserrenderImageGallery', [ &$parser, &$ig ] ); $lines = StringUtils::explode( "\n", $text ); foreach ( $lines as $line ) { diff --git a/includes/rcfeed/FormattedRCFeed.php b/includes/rcfeed/FormattedRCFeed.php new file mode 100644 index 0000000000..48a9f946a5 --- /dev/null +++ b/includes/rcfeed/FormattedRCFeed.php @@ -0,0 +1,68 @@ +params = $params; + } + + /** + * Send some text to the specified feed. + * + * @param array $feed The feed, as configured in an associative array + * @param string $line The text to send + * @return bool Success + */ + abstract public function send( array $feed, $line ); + + /** + * @param RecentChange $rc + * @param string|null $actionComment + * @return bool Success + */ + public function notify( RecentChange $rc, $actionComment = null ) { + $params = $this->params; + /** @var $formatter RCFeedFormatter */ + $formatter = is_object( $params['formatter'] ) ? $params['formatter'] : new $params['formatter']; + + $line = $formatter->getLine( $params, $rc, $actionComment ); + if ( !$line ) { + // @codeCoverageIgnoreStart + // T109544 - If a feed formatter returns null, this will otherwise cause an + // error in at least RedisPubSubFeedEngine. Not sure best to handle this. + return; + // @codeCoverageIgnoreEnd + } + return $this->send( $params, $line ); + } +} diff --git a/includes/rcfeed/RCFeed.php b/includes/rcfeed/RCFeed.php new file mode 100644 index 0000000000..7e9ce606ad --- /dev/null +++ b/includes/rcfeed/RCFeed.php @@ -0,0 +1,59 @@ +register( include "$IP/resources/ResourcesOOUI.php" ); // Register extension modules $this->register( $config->get( 'ResourceModules' ) ); - Hooks::run( 'ResourceLoaderRegisterModules', [ &$this ] ); + + // Avoid PHP 7.1 warning from passing $this by reference + $rl = $this; + Hooks::run( 'ResourceLoaderRegisterModules', [ &$rl ] ); if ( $config->get( 'EnableJavaScriptTest' ) === true ) { $this->registerTestModules(); @@ -404,7 +407,9 @@ class ResourceLoader implements LoggerAwareInterface { $testModules = []; $testModules['qunit'] = []; // Get other test suites (e.g. from extensions) - Hooks::run( 'ResourceLoaderTestModules', [ &$testModules, &$this ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $rl = $this; + Hooks::run( 'ResourceLoaderTestModules', [ &$testModules, &$rl ] ); // Add the testrunner (which configures QUnit) to the dependencies. // Since it must be ready before any of the test suites are executed. diff --git a/includes/skins/BaseTemplate.php b/includes/skins/BaseTemplate.php index 65eb9b776e..eef421c46e 100644 --- a/includes/skins/BaseTemplate.php +++ b/includes/skins/BaseTemplate.php @@ -112,7 +112,9 @@ abstract class BaseTemplate extends QuickTemplate { $toolbox['info']['id'] = 't-info'; } - Hooks::run( 'BaseTemplateToolbox', [ &$this, &$toolbox ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $template = $this; + Hooks::run( 'BaseTemplateToolbox', [ &$template, &$toolbox ] ); return $toolbox; } @@ -227,7 +229,9 @@ abstract class BaseTemplate extends QuickTemplate { ob_start(); // We pass an extra 'true' at the end so extensions using BaseTemplateToolbox // can abort and avoid outputting double toolbox links - Hooks::run( 'SkinTemplateToolboxEnd', [ &$this, true ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $template = $this; + Hooks::run( 'SkinTemplateToolboxEnd', [ &$template, true ] ); $hookContents = ob_get_contents(); ob_end_clean(); if ( !trim( $hookContents ) ) { diff --git a/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php index 298d6c4edb..0281b15a0e 100644 --- a/includes/specials/SpecialMovepage.php +++ b/includes/specials/SpecialMovepage.php @@ -630,7 +630,9 @@ class MovePageForm extends UnlistedSpecialPage { $newLink )->params( $oldText, $newText )->parseAsBlock() ); $out->addWikiMsg( $msgName ); - Hooks::run( 'SpecialMovepageAfterMove', [ &$this, &$ot, &$nt ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $movePage = $this; + Hooks::run( 'SpecialMovepageAfterMove', [ &$movePage, &$ot, &$nt ] ); # Now we move extra pages we've been asked to move: subpages and talk # pages. First, if the old page or the new page is a talk page, we diff --git a/includes/specials/SpecialUserrights.php b/includes/specials/SpecialUserrights.php index b0808f6585..454d1e3b35 100644 --- a/includes/specials/SpecialUserrights.php +++ b/includes/specials/SpecialUserrights.php @@ -257,6 +257,7 @@ class UserrightsPage extends SpecialPage { $addgroup = []; $groupExpiries = []; // associative array of (group name => expiry) $removegroup = []; + $existingUGMs = $user->getGroupMemberships(); // This could possibly create a highly unlikely race condition if permissions are changed between // when the form is loaded and when the form is saved. Ignoring it for the moment. @@ -269,12 +270,14 @@ class UserrightsPage extends SpecialPage { if ( $this->canProcessExpiries() ) { // read the expiry information from the request $expiryDropdown = $this->getRequest()->getVal( "wpExpiry-$group" ); + if ( $expiryDropdown === 'existing' ) { + continue; + } + if ( $expiryDropdown === 'other' ) { $expiryValue = $this->getRequest()->getVal( "wpExpiry-$group-other" ); - } elseif ( $expiryDropdown !== 'existing' ) { - $expiryValue = $expiryDropdown; } else { - continue; + $expiryValue = $expiryDropdown; } // validate the expiry @@ -288,6 +291,16 @@ class UserrightsPage extends SpecialPage { if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) { return Status::newFatal( 'userrights-expiry-in-past', $group ); } + + // if the user can only add this group (not remove it), the expiry time + // cannot be brought forward (T156784) + if ( !$this->canRemove( $group ) && + isset( $existingUGMs[$group] ) && + ( $existingUGMs[$group]->getExpiry() ?: 'infinity' ) > + ( $groupExpiries[$group] ?: 'infinity' ) + ) { + return Status::newFatal( 'userrights-cannot-shorten-expiry', $group ); + } } } else { $removegroup[] = $group; @@ -300,7 +313,8 @@ class UserrightsPage extends SpecialPage { } /** - * Save user groups changes in the database. + * Save user groups changes in the database. This function does not throw errors; + * instead, it ignores groups that the performer does not have permission to set. * * @param User|UserRightsProxy $user * @param array $add Array of groups to add @@ -317,6 +331,7 @@ class UserrightsPage extends SpecialPage { // Validate input set... $isself = $user->getName() == $this->getUser()->getName(); $groups = $user->getGroups(); + $ugms = $user->getGroupMemberships(); $changeable = $this->changeableGroups(); $addable = array_merge( $changeable['add'], $isself ? $changeable['add-self'] : [] ); $removable = array_merge( $changeable['remove'], $isself ? $changeable['remove-self'] : [] ); @@ -325,9 +340,19 @@ class UserrightsPage extends SpecialPage { array_intersect( (array)$remove, $removable, $groups ) ); $add = array_intersect( (array)$add, $addable ); - // add only groups that are not already present or that need their expiry updated + // add only groups that are not already present or that need their expiry updated, + // UNLESS the user can only add this group (not remove it) and the expiry time + // is being brought forward (T156784) $add = array_filter( $add, - function( $group ) use ( $groups, $groupExpiries ) { + function( $group ) use ( $groups, $groupExpiries, $removable, $ugms ) { + if ( isset( $groupExpiries[$group] ) && + !in_array( $group, $removable ) && + isset( $ugms[$group] ) && + ( $ugms[$group]->getExpiry() ?: 'infinity' ) > + ( $groupExpiries[$group] ?: 'infinity' ) + ) { + return false; + } return !in_array( $group, $groups ) || array_key_exists( $group, $groupExpiries ); } ); @@ -757,22 +782,30 @@ class UserrightsPage extends SpecialPage { foreach ( $allgroups as $group ) { $set = isset( $usergroups[$group] ); + // Users who can add the group, but not remove it, can only lengthen + // expiries, not shorten them. So they should only see the expiry + // dropdown if the group currently has a finite expiry + $canOnlyLengthenExpiry = ( $set && $this->canAdd( $group ) && + !$this->canRemove( $group ) && $usergroups[$group]->getExpiry() ); // Should the checkbox be disabled? - $disabled = !( + $disabledCheckbox = !( ( $set && $this->canRemove( $group ) ) || ( !$set && $this->canAdd( $group ) ) ); + // Should the expiry elements be disabled? + $disabledExpiry = $disabledCheckbox && !$canOnlyLengthenExpiry; // Do we need to point out that this action is irreversible? - $irreversible = !$disabled && ( + $irreversible = !$disabledCheckbox && ( ( $set && !$this->canAdd( $group ) ) || ( !$set && !$this->canRemove( $group ) ) ); $checkbox = [ 'set' => $set, - 'disabled' => $disabled, + 'disabled' => $disabledCheckbox, + 'disabled-expiry' => $disabledExpiry, 'irreversible' => $irreversible ]; - if ( $disabled ) { + if ( $disabledCheckbox && $disabledExpiry ) { $columns['unchangeable'][$group] = $checkbox; } else { $columns['changeable'][$group] = $checkbox; @@ -806,12 +839,14 @@ class UserrightsPage extends SpecialPage { $member = UserGroupMembership::getGroupMemberName( $group, $user->getName() ); if ( $checkbox['irreversible'] ) { $text = $this->msg( 'userrights-irreversible-marker', $member )->text(); + } elseif ( $checkbox['disabled'] && !$checkbox['disabled-expiry'] ) { + $text = $this->msg( 'userrights-no-shorten-expiry-marker', $member )->text(); } else { $text = $member; } $checkboxHtml = Xml::checkLabel( $text, "wpGroup-" . $group, "wpGroup-" . $group, $checkbox['set'], $attr ); - $ret .= "\t\t" . ( $checkbox['disabled'] + $ret .= "\t\t" . ( ( $checkbox['disabled'] && $checkbox['disabled-expiry'] ) ? Xml::tags( 'div', [ 'class' => 'mw-userrights-disabled' ], $checkboxHtml ) : Xml::tags( 'div', [], $checkboxHtml ) ) . "\n"; @@ -824,9 +859,11 @@ class UserrightsPage extends SpecialPage { $usergroups[$group]->getExpiry() : null; - // If the user can't uncheck this checkbox, print the current expiry below + // If the user can't modify the expiry, print the current expiry below // it in plain text. Otherwise provide UI to set/change the expiry - if ( $checkbox['set'] && ( $checkbox['irreversible'] || $checkbox['disabled'] ) ) { + if ( $checkbox['set'] && + ( $checkbox['irreversible'] || $checkbox['disabled-expiry'] ) + ) { if ( $currentExpiry ) { $expiryFormatted = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser ); $expiryFormattedD = $uiLanguage->userDate( $currentExpiry, $uiUser ); @@ -848,7 +885,7 @@ class UserrightsPage extends SpecialPage { "mw-input-wpExpiry-$group", // forward compatibility with HTMLForm $currentExpiry ? 'existing' : 'infinite' ); - if ( $checkbox['disabled'] ) { + if ( $checkbox['disabled-expiry'] ) { $expiryFormOptions->setAttribute( 'disabled', 'disabled' ); } @@ -883,11 +920,17 @@ class UserrightsPage extends SpecialPage { // Add custom expiry field $attribs = [ 'id' => "mw-input-wpExpiry-$group-other" ]; - if ( $checkbox['disabled'] ) { + if ( $checkbox['disabled-expiry'] ) { $attribs['disabled'] = 'disabled'; } $expiryHtml .= Xml::input( "wpExpiry-$group-other", 30, '', $attribs ); + // If the user group is set but the checkbox is disabled, mimic a + // checked checkbox in the form submission + if ( $checkbox['set'] && $checkbox['disabled'] ) { + $expiryHtml .= Html::hidden( "wpGroup-$group", 1 ); + } + $expiryHtml .= Xml::closeElement( 'span' ); } diff --git a/includes/specials/SpecialWantedpages.php b/includes/specials/SpecialWantedpages.php index c37ecbd17a..8cea6ccb77 100644 --- a/includes/specials/SpecialWantedpages.php +++ b/includes/specials/SpecialWantedpages.php @@ -85,7 +85,9 @@ class WantedPagesPage extends WantedQueryPage { ] ]; // Replacement for the WantedPages::getSQL hook - Hooks::run( 'WantedPages::getQueryInfo', [ &$this, &$query ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $wantedPages = $this; + Hooks::run( 'WantedPages::getQueryInfo', [ &$wantedPages, &$query ] ); return $query; } diff --git a/includes/specials/pagers/ActiveUsersPager.php b/includes/specials/pagers/ActiveUsersPager.php index 1fec05d39d..0d6f493d59 100644 --- a/includes/specials/pagers/ActiveUsersPager.php +++ b/includes/specials/pagers/ActiveUsersPager.php @@ -111,7 +111,9 @@ class ActiveUsersPager extends UsersPager { 'user_groups', '1', [ 'ug_user = user_id', 'ug_group' => $group, - 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() ) + $this->getConfig()->get( 'DisableUserGroupExpiry' ) ? + '1' : + 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() ) ] ) . ')'; } diff --git a/includes/specials/pagers/ContribsPager.php b/includes/specials/pagers/ContribsPager.php index 367d07304f..0c3a21108b 100644 --- a/includes/specials/pagers/ContribsPager.php +++ b/includes/specials/pagers/ContribsPager.php @@ -200,7 +200,9 @@ class ContribsPager extends ReverseChronologicalPager { $this->tagFilter ); - Hooks::run( 'ContribsPager::getQueryInfo', [ &$this, &$queryInfo ] ); + // Avoid PHP 7.1 warning from passing $this by reference + $pager = $this; + Hooks::run( 'ContribsPager::getQueryInfo', [ &$pager, &$queryInfo ] ); return $queryInfo; } diff --git a/includes/specials/pagers/NewPagesPager.php b/includes/specials/pagers/NewPagesPager.php index e298f103a2..dafd244ee5 100644 --- a/includes/specials/pagers/NewPagesPager.php +++ b/includes/specials/pagers/NewPagesPager.php @@ -100,8 +100,10 @@ class NewPagesPager extends ReverseChronologicalPager { ]; $join_conds = [ 'page' => [ 'INNER JOIN', 'page_id=rc_cur_id' ] ]; + // Avoid PHP 7.1 warning from passing $this by reference + $pager = $this; Hooks::run( 'SpecialNewpagesConditions', - [ &$this, $this->opts, &$conds, &$tables, &$fields, &$join_conds ] ); + [ &$pager, $this->opts, &$conds, &$tables, &$fields, &$join_conds ] ); $options = []; diff --git a/includes/widget/DateInputWidget.php b/includes/widget/DateInputWidget.php index f011f0b8af..507dab6fac 100644 --- a/includes/widget/DateInputWidget.php +++ b/includes/widget/DateInputWidget.php @@ -19,6 +19,7 @@ class DateInputWidget extends \OOUI\TextInputWidget { protected $inputFormat = null; protected $displayFormat = null; + protected $longDisplayFormat = null; protected $placeholderLabel = null; protected $placeholderDateFormat = null; protected $precision = null; @@ -36,6 +37,9 @@ class DateInputWidget extends \OOUI\TextInputWidget { * while the widget is inactive. Should be as unambiguous as possible (for example, prefer * to spell out the month, rather than rely on the order), even if that makes it longer. * Applicable only if the widget is infused. (default: language-specific) + * @param string $config['longDisplayFormat'] If a custom displayFormat is not specified, use + * unabbreviated day of the week and month names in the default language-specific + * displayFormat. (default: false) * @param string $config['placeholderLabel'] Placeholder text shown when the widget is not * selected. Applicable only if the widget is infused. (default: taken from message * `mw-widgets-dateinput-no-date`) @@ -58,6 +62,7 @@ class DateInputWidget extends \OOUI\TextInputWidget { $config = array_merge( [ // Default config values 'precision' => 'day', + 'longDisplayFormat' => false, ], $config ); // Properties @@ -79,6 +84,9 @@ class DateInputWidget extends \OOUI\TextInputWidget { if ( isset( $config['displayFormat'] ) ) { $this->displayFormat = $config['displayFormat']; } + if ( isset( $config['longDisplayFormat'] ) ) { + $this->longDisplayFormat = $config['longDisplayFormat']; + } if ( isset( $config['placeholderLabel'] ) ) { $this->placeholderLabel = $config['placeholderLabel']; } @@ -134,6 +142,9 @@ class DateInputWidget extends \OOUI\TextInputWidget { if ( $this->displayFormat !== null ) { $config['displayFormat'] = $this->displayFormat; } + if ( $this->longDisplayFormat !== null ) { + $config['longDisplayFormat'] = $this->longDisplayFormat; + } if ( $this->placeholderLabel !== null ) { $config['placeholderLabel'] = $this->placeholderLabel; } diff --git a/includes/widget/UsersMultiselectWidget.php b/includes/widget/UsersMultiselectWidget.php new file mode 100644 index 0000000000..d24ab7bf66 --- /dev/null +++ b/includes/widget/UsersMultiselectWidget.php @@ -0,0 +1,68 @@ +usersArray = $config['default']; + } + if ( isset( $config['name'] ) ) { + $this->inputName = $config['name']; + } + if ( isset( $config['placeholder'] ) ) { + $this->inputPlaceholder = $config['placeholder']; + } + + $textarea = new TextInputWidget( [ + 'name' => $this->inputName, + 'multiline' => true, + 'value' => implode( "\n", $this->usersArray ), + 'rows' => 25, + ] ); + $this->prependContent( $textarea ); + } + + protected function getJavaScriptClassName() { + return 'mw.widgets.UsersMultiselectWidget'; + } + + public function getConfig( &$config ) { + if ( $this->usersArray !== null ) { + $config['data'] = $this->usersArray; + } + if ( $this->inputName !== null ) { + $config['name'] = $this->inputName; + } + if ( $this->inputPlaceholder !== null ) { + $config['placeholder'] = $this->inputPlaceholder; + } + + return parent::getConfig( $config ); + } + +} diff --git a/languages/Language.php b/languages/Language.php index 68727bb233..a1cc4bc9f2 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -4508,7 +4508,7 @@ class Language { # such as action=raw much more expensive than they need to be. # This will hopefully cover most cases. $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i', - [ &$this, 'replaceGrammarInNamespace' ], $talk ); + [ $this, 'replaceGrammarInNamespace' ], $talk ); return str_replace( ' ', '_', $talk ); } diff --git a/languages/i18n/be-tarask.json b/languages/i18n/be-tarask.json index f13bf53f7c..f3d563ad08 100644 --- a/languages/i18n/be-tarask.json +++ b/languages/i18n/be-tarask.json @@ -796,7 +796,7 @@ "last": "папярэдняя", "page_first": "першая", "page_last": "апошняя", - "histlegend": "Параўнаньне: пазначце кропкамі дзьве вэрсіі для параўнаньня і націсьніце enter альбо кнопку ўнізе.
\nТлумачэньне: (цяп) = адрозьненьні ад цяперашняй вэрсіі, (папярэдняя) = адрозьненьні ад папярэдняй вэрсіі, д = дробная праўка.", + "histlegend": "Параўнаньне: пазначце кропкамі дзьве вэрсіі для параўнаньня і націсьніце «ўвод» альбо кнопку ўнізе.
\nТлумачэньне: ({{int:cur}}) = адрозьненьні ад цяперашняй вэрсіі, ({{int:last}}) = адрозьненьні ад папярэдняй вэрсіі, {{int:minoreditletter}} = дробная праўка.", "history-fieldset-title": "Пошук у гісторыі", "history-show-deleted": "Толькі выдаленыя", "histfirst": "найстарэйшыя", @@ -1102,6 +1102,8 @@ "userrights-expiry-current": "Сканчаецца $1", "userrights-expiry-none": "Бестэрмінова", "userrights-expiry": "Сканчаецца:", + "userrights-expiry-existing": "Цяперашні час сканчэньня: $3 $2", + "userrights-expiry-othertime": "Іншы час:", "userrights-conflict": "Канфлікт пры зьмене правоў удзельнікаў! Калі ласка, праверце і захавайце вашыя зьмены.", "group": "Група:", "group-user": "Удзельнікі", diff --git a/languages/i18n/be.json b/languages/i18n/be.json index e9301d83b0..03084d667f 100644 --- a/languages/i18n/be.json +++ b/languages/i18n/be.json @@ -1056,6 +1056,7 @@ "youremail": "Эл.пошта *", "username": "Імя {{GENDER:$1|ўдзельніка|ўдзельніцы}}:", "prefs-memberingroups": "Уваходзіць у {{PLURAL:$1|групу|групы}}:", + "group-membership-link-with-expiry": "$1 (да $2)", "prefs-registration": "Час рэгістрацыі:", "yourrealname": "Сапраўднае імя:", "yourlanguage": "Мова:", @@ -1111,6 +1112,11 @@ "userrights-nodatabase": "Не знойдзена тут, або не існуе база даных $1.", "userrights-changeable-col": "Групы, якія вам дазволена мяняць", "userrights-unchangeable-col": "Групы, якія вам не дазволена мяняць", + "userrights-expiry-current": "Канчаецца $1", + "userrights-expiry-none": "Бестэрмінова", + "userrights-expiry": "Канчаецца:", + "userrights-expiry-existing": "Цяперашні час сканчэння: $3, $2", + "userrights-expiry-othertime": "Іншы час:", "userrights-conflict": "Канфлікт змянення ўдзельніцкіх дазволаў! Калі ласка, праверце і пацвердзіце змены.", "group": "Група:", "group-user": "Удзельнікі", @@ -1312,6 +1318,7 @@ "recentchanges-submit": "Паказаць", "rcfilters-filter-userExpLevel-learner-description": "Болей дзён актыўнасці і правак, чым у «навічкоў», але меней чым у «дасведчаных удзельнікаў».", "rcfilters-filter-userExpLevel-experienced-description": "Больш за 30 дзён актыўнасці і 500 правак.", + "rcfilters-filter-bots-label": "Бот", "rcnotefrom": "Ніжэй {{PLURAL:$5|паказана змяненне|паказаны змены}} з $3, $4 (не больш за $1).", "rclistfrom": "Паказаць змены з $3 $2", "rcshowhideminor": "$1 дробныя праўкі", diff --git a/languages/i18n/bho.json b/languages/i18n/bho.json index d55a523f9b..f63d25e800 100644 --- a/languages/i18n/bho.json +++ b/languages/i18n/bho.json @@ -187,11 +187,11 @@ "create-local": "लोकल विवरण जोड़ीं", "editthispage": "ए पन्ना के संपादन करीं", "create-this-page": "ई पन्ना बनाईं", - "delete": "मिटाईं", - "deletethispage": "ई पन्ना के मिटाईं", - "undeletethispage": "ई पन्ना के फिर से स्थापित करीं", - "undelete_short": "{{PLURAL:$1|एक ठो हटावल गइल संपादन|$1 ठे हटावल गइल संपादन कुल}} बिनामेटावल करीं", - "viewdeleted_short": "{{PLURAL:$1|एक ठो हटावल गइल संपादन|$1 हटावल गइल संपादन कुल}} देखीं", + "delete": "हटाईं", + "deletethispage": "ए पन्ना के हटाईं", + "undeletethispage": "हटावल पन्ना वापस ले आईं", + "undelete_short": "{{PLURAL:$1|एक ठो हटावल गइल संपादन|$1 ठे हटावल गइल संपादन कुल}} वापस ले आईं", + "viewdeleted_short": "{{PLURAL:$1|एक ठो हटावल गइल संपादन|$1 हटावल गइल संपादन}} देखीं", "protect": "सुरक्षित करीं", "protect_change": "बदलीं", "protectthispage": "ए पन्ना के सुरक्षित करीं।", @@ -204,13 +204,13 @@ "personaltools": "निजी औजार", "articlepage": "सामग्री पन्ना देखीं", "talk": "बातचीत", - "views": "व्यू", + "views": "बिबिध रूप", "toolbox": "औजार", "tool-link-userrights": "{{GENDER:$1|प्रयोगकर्ता}} के मंडली बदलीं", "tool-link-userrights-readonly": "{{GENDER:$1|प्रयोगकर्ता}} मंडली देखीं", "tool-link-emailuser": "{{GENDER:$1|प्रयोगकर्ता}} के ईमेल करीं", "userpage": "प्रयोगकर्ता पन्ना देखीं", - "projectpage": "परियोजना पन्ना देखीं", + "projectpage": "प्रोजेक्ट पन्ना देखीं", "imagepage": "फाइल पन्ना देखीं", "mediawikipage": "सनेसा पन्ना देखीं", "templatepage": "टेम्पलेट पन्ना देखीं", @@ -229,8 +229,8 @@ "jumptosearch": "खोजीं", "view-pool-error": "माफ करीं, ए समय सर्वर पर बहुत ज्यादा लोड बढ़ गइल बा।\nए पन्ना के बहुते प्रयोगकर्ता लोग देखे के कोशिश कर रहल बा।\nए पन्ना के फिर से देखे से पहिले कृपया कुछ देर तक इंतजार करीं।\n\n$1", "generic-pool-error": "माफ करीं, ए समय सर्वर पर बहुत ज्यादा लोड बढ़ गइल बा।\nए संसाधन के बहुते प्रयोगकर्ता लोग देखे के कोशिश कर रहल बा।\nए संसाधन तक पहुँच बनावे के कोशिश से पहिले कृपया कुछ देर तक इंतजार करीं।", - "pool-timeout": "तालाबन्दी खातिर इंतजार समय समाप्त", - "pool-queuefull": "पूल पंक्ति भर गइल", + "pool-timeout": "तालाबंदी खुले के इंतजार समय समाप्त", + "pool-queuefull": "पूल कतार भरल बा", "pool-errorunknown": "नामालूम खराबी", "pool-servererror": "पूल काउंटर सर्विस उपलब्ध नइखे ($1)।", "poolcounter-usage-error": "इस्तमाल खराबी: $1", @@ -254,12 +254,12 @@ "badaccess": "परमीशन खराबी", "badaccess-group0": "जवन कार्रवाई के माँग कइले बानी, ओकरा लागू करे के इजाजत रउआँ के नइखे।", "badaccess-groups": "रउआ जौन कारवाई के माँग कइले बानी ऊ {{PLURAL:$2|$1 मंडली|$1 मंडली सभ}} के सदस्य लोग भर कर सकत बा।", - "versionrequired": "मिडीयाविकी के संस्करण $1 के होखल जरुरी बा", + "versionrequired": "मिडीयाविकी के वर्शन $1 के होखल जरुरी बा", "versionrequiredtext": "ए पन्ना के प्रयोग करे खातिर मीडियाविकी के वर्शन $1 जरूरी बा।\n[[Special:Version|वर्शन पन्ना]] देखीं।", "ok": "ठीक", "retrievedfrom": "\"$1\" से लिहल गइल", - "youhavenewmessages": "रउआ लगे बा $1 ($2).", - "youhavenewmessagesfromusers": "{{PLURAL:$4|रउवाँ खातिर}}{{PLURAL:$3|अउरी प्रयोगकर्ता के|$3 प्रयोगकर्ता लोग}} के $1 बा ($2)।", + "youhavenewmessages": "{{PLURAL:$3|रउआँ खातिर}} $1 ($2) बा।", + "youhavenewmessagesfromusers": "{{PLURAL:$4|रउवाँ खातिर}}{{PLURAL:$3|केहू प्रयोगकर्ता के|$3 प्रयोगकर्ता लोग}} के $1 बा ($2)।", "youhavenewmessagesmanyusers": "रउवाँ खातिर कई प्रयोगकर्ता लोग के भेजल $1 बा ($2)।", "newmessageslinkplural": "{{PLURAL:$1|नया सनेसा|999=नया सनेसा सभ}}", "newmessagesdifflinkplural": "पिछला {{PLURAL:$1|बदलाव|999=बदलाव}}", @@ -282,13 +282,13 @@ "viewdeleted": "$1 देखावल जाय?", "restorelink": "{{PLURAL:$1|एक ठो हटावल संपादन|$1 ठे हटावल संपादन}}", "feedlinks": "फीड:", - "feed-invalid": "अवैध सबस्क्रिप्शन फीड प्रकार", + "feed-invalid": "अवैध सबस्क्रिप्शन फीड प्रकार।", "feed-unavailable": "सिंडिकेशन फीड उपलब्ध नइखें", "site-rss-feed": "$1 आरएसएस फीड", "site-atom-feed": "$1 एटम फीड", - "page-rss-feed": "\"$1\" आरएसएस फिड", + "page-rss-feed": "\"$1\" आरएसएस फीड", "page-atom-feed": "\"$1\" एटम फीड", - "red-link-title": "$1 (पन्ना मौजूद नइखे)।", + "red-link-title": "$1 (पन्ना मौजूद नइखे)", "sort-descending": "उतरत क्रम में", "sort-ascending": "चढ़त क्रम में", "nstab-main": "पन्ना", @@ -303,7 +303,7 @@ "nstab-category": "श्रेणी", "mainpage-nstab": "मुख्य पन्ना", "nosuchaction": "अइसन कौनो कार्रवाई नइखे", - "nosuchactiontext": "ए यू॰आर॰एल द्वारा बतावल कार्रवाई अवैध बा।\nरउवाँ यू॰आर॰एल गलत लिखले होखब, या कव्नो गलत कड़ी के इस्तेमाल कइले होखब।\n{{SITENAME}} में इस्तमाल हो रहल सॉफ्टवेयर में खराबी के लच्छन भी हो सकत बा।", + "nosuchactiontext": "ए यू॰आर॰एल द्वारा बतावल कार्रवाई अवैध बा।\nरउवाँ यू॰आर॰एल गलत लिखले होखब, या कौनों गलत कड़ी के इस्तेमाल कइले होखब।\n{{SITENAME}} में इस्तमाल हो रहल सॉफ्टवेयर में खराबी के लच्छन भी हो सकत बा।", "nosuchspecialpage": "अइसन कौनो खास पन्ना नइखे", "nospecialpagetext": "रउआँ एगो अवैध खास पन्ना के अनुरोध कइले बानी।\n\nबैध खास पन्नासभ के लिस्ट [[Special:SpecialPages|{{int:specialpages}}]] पर देखल जा सकत बा।", "error": "खराबी", @@ -315,7 +315,7 @@ "databaseerror-error": "खराबी: $1", "transaction-duration-limit-exceeded": "हाई रिप्लिकेशन लैग बनावे से बचे खातिर ई ट्रांजेक्शन निरस्त कर दिहल गइल, काहें से की राइट करे में लागे वाला समय ($1), $2 के सीमा से अधिक रहल ह।\nअगर आप कई ठो आइटम एकही साथ बदलत होखीं, तब कई टुकड़ा में ई काम करे के कोसिस करीं।", "laggedslavemode": "चेतावनी: अइसन भी हो सकेला कि पन्ना पर हाल के अपडेट न होखे।", - "readonly": "डेटाबेस तालाबंदी बा", + "readonly": "डेटाबेस तालाबंद बा", "enterlockreason": "तालाबंदी के कारण दीं, आ अनुमान बताईं कि कब तालाबंदी हटी", "readonlytext": "नया संपादन आ अन्य बदलाव खातिर डाटाबेस पर तालाबंदी बा, शायद रुटीन मेंटेनन्स के चलते, जेकरा बाद ए के सामान्य स्थिती में आ जाये के चाहीं।\n\nतालाबंदी करे वाला सिस्टम प्रबंधक के बतावल कारण: $1", "missing-article": "डेटाबास के ओ पन्ना के पाठ ना मिलल जवन मिले के चाहत रहल, एकर नाँव रहल \"$1\" $2।\nआमतौर पर अइसन तब होला पुरान हो चुकल अंतर या हटावल पन्ना के इतिहास के कड़ी के पीछा कइल जा रहल होखे।\n\nयदि ई बात नइखे, तब हो सकेला आपके कौनों सॉफ्टवेयर बग मिल गइल होखे।\n[[Special:ListUsers/sysop|प्रबंधक]] के ई यूआरएल दे के खबर करीं।", @@ -388,15 +388,15 @@ "cannotlogoutnow-text": "$1 के इस्तेमाल करत समय लॉगआउट नइखे संभव।", "welcomeuser": "राउर स्वागत बा, $1!", "welcomecreation-msg": "राउर खाता बना दिहल गईल बा।\nआपन [[Special:Preferences|{{SITENAME}} वरीयतां]] के बदले के ना भूलब।", - "yourname": "सदस्यनाम:", - "userlogin-yourname": "सदस्यनाँव", - "userlogin-yourname-ph": "आपन सदस्यनाँव लिखीं", - "createacct-another-username-ph": "सदस्यनाम लिखीं", - "yourpassword": "गुप्त शब्द", + "yourname": "प्रयोगकर्तानाँव:", + "userlogin-yourname": "प्रयोगकर्तानाँव", + "userlogin-yourname-ph": "आपन प्रयोगकर्तानाँव लिखीं", + "createacct-another-username-ph": "प्रयोगकर्तानाँव लिखीं", + "yourpassword": "गुप्तशब्द:", "userlogin-yourpassword": "गुप्तशब्द (पासवर्ड)", "userlogin-yourpassword-ph": "आपन गुप्तशब्द लिखीं", "createacct-yourpassword-ph": "एगो गुप्तशब्द (पासवर्ड) प्रवेश करीं", - "yourpasswordagain": "गुप्त-शब्द पुन:डालीं:", + "yourpasswordagain": "गुप्तशब्द दोबारा डालीं:", "createacct-yourpasswordagain": "गुप्तशब्द (पासवर्ड) के पुष्टि करीं", "createacct-yourpasswordagain-ph": "गुप्तशब्द (पासवर्ड) फेर से प्रवेश करीं", "userlogin-remembermypassword": "हमके लॉग इन रहे दीं", @@ -417,7 +417,7 @@ "userloginnocreate": "खाता में प्रवेश", "logout": "खाता से बाहर", "userlogout": "खाता से बाहर", - "notloggedin": "खाता में प्रवेश नईखीं भईल", + "notloggedin": "खाता में प्रवेश नइखीं भइल", "userlogin-noaccount": "का एगो खाता नइखे?", "userlogin-joinproject": "{{SITENAME}} से जुड़ीं", "nologin": "का एगो खाता नईखे? $1.", @@ -425,100 +425,100 @@ "createaccount": "खाता बनाईं", "gotaccount": "का पहिले से एगो खाता बा? $1.", "gotaccountlink": "खाता में प्रवेश", - "userlogin-resetlink": "का रउआ आपन प्रवेश जानकारी भूला गइल बानी?", - "userlogin-resetpassword-link": "आपन गुप्तशब्द भूला गईनी का?", - "userlogin-helplink2": "लॉग इन में मदद", - "userlogin-loggedin": "रउआ {{GENDER:$1|$1}} के रूप में पहिले से लॉग्ड इन बानीं।\nकौनो अन्य सदस्य के रूप में लॉग इन करे खातिर निम्नलिखित फ़ॉर्म के प्रयोग करीं।", - "userlogin-reauth": "आप के ई साबित करे खातिर की आपे {{GENDER:$1|$1}} बानी, दुबारा लॉगिन करे के पड़ी।", + "userlogin-resetlink": "का रउआ आपन खाता में प्रवेश वाली जानकारी भुला गइल बानी?", + "userlogin-resetpassword-link": "आपन गुप्तशब्द भुला गइनी का?", + "userlogin-helplink2": "खाता में प्रवेश में मदद", + "userlogin-loggedin": "रउआ {{GENDER:$1|$1}} के रूप में पहिले से खाता में प्रवेश क चुकल बानीं।\nकौनो अन्य सदस्य के रूप में खाता में प्रवेश करे खातिर नीचे दिहल फारम के प्रयोग करीं।", + "userlogin-reauth": "आप के ई साबित करे खातिर की आपे {{GENDER:$1|$1}} बानी, दुबारा खाता में प्रवेश करे के पड़ी।", "userlogin-createanother": "एगो दूसर खाता बनाईं", - "createacct-emailrequired": "ई-मेल पता", - "createacct-emailoptional": "ई-मेल पता (वैकल्पिक)", - "createacct-email-ph": "आपन ई-मेल पता लिखीं", - "createacct-another-email-ph": "ई-मेल पता लिखीं", - "createaccountmail": "एगो अस्थायी यादृच्छिक (रैन्डम) गुप्तशब्द के प्रयोग करीं आ निर्दिष्ट ई-मेल पता पर भेजीं", + "createacct-emailrequired": "ईमेल पता", + "createacct-emailoptional": "ईमेल पता (वैकल्पिक)", + "createacct-email-ph": "आपन ईमेल पता लिखीं", + "createacct-another-email-ph": "ईमेल पता लिखीं", + "createaccountmail": "एगो अस्थायी यादृच्छिक (रैन्डम) गुप्तशब्द के प्रयोग करीं आ दिहल गइल ईमेल पता पर भेजीं", "createaccountmail-help": "एकर इस्तेमाल केहू दुसरा खातिर खाता बनावे में कइल जा सके ला, बिना पासवर्ड जनले।", "createacct-realname": "असली नाम (वैकल्पिक)", "createaccountreason": "कारण:", "createacct-reason": "कारण", - "createacct-reason-ph": "रउआ एगो अन्य खाता काहे बना रहल बानी", - "createacct-reason-help": "खाता बनवले के लॉग में देखाई पड़े वाला संदेस", + "createacct-reason-ph": "रउआ एगो अन्य खाता काहें बना रहल बानी", + "createacct-reason-help": "खाता बनवले के लॉग में देखाई पड़े वाला सनेसा", "createacct-submit": "आपन खाता बनाईं", "createacct-another-submit": "खाता बनाईं", "createacct-continue-submit": "खाता बनावल जारी राखीं", "createacct-another-continue-submit": "खाता बनावल जारी राखीं", - "createacct-benefit-heading": "{{SITENAME}} रउआ जइसन लोगन द्वारा बनावल गईल बा।", + "createacct-benefit-heading": "{{SITENAME}} रउआ जइसन लोगन द्वारा बनावल गइल बा।", "createacct-benefit-body1": "{{PLURAL:$1|संपादन}}", "createacct-benefit-body2": "{{PLURAL:$1|पन्ना}}", "createacct-benefit-body3": "हाल के {{PLURAL:$1|योगदानकर्ता}}", - "badretype": "रउआ जौन गुप्त शब्द डालत बानी उ नईखे मेल खात।", - "usernameinprogress": "एही सदस्यनाँव खातिर खाता खोले के काम पहिलहीं चालू बा।\nइंतजार करीं।", - "userexists": "लिखल गईल सदस्य नाम पहिले से प्रयोग में बा। कृपया कौनो दोसर नाम चुनीं।", - "loginerror": "खाता प्रवेश में त्रुटि", - "createacct-error": "खाता निर्माण त्रुटि", - "createaccounterror": "ई खाता ना बन पाईल: $1", - "nocookiesnew": "प्रयोगकर्ता खाता त बन गईल, बाँकी रउआ प्रवेश नईखीं भईल।\n{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।\nराउर कुकिज असक्षम बा।\nकृपया उ के सक्षम करीं, उ के बाद राउर नया प्रयोगकर्ता नाम आ गुप्त शब्द के साथ प्रवेश करीं।", - "nocookieslogin": "{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।\nराउर कुकिज असक्षम बा।\nकृपया उ के सक्षम करीं आ फिर से कोशिश करीं", - "nocookiesfornew": "स्रोत के पुष्टि ना हो पावे के कारण इ खाता निर्मित ना करल गइल। \nसुनिश्चित करीं कि रउआ कुकीज़ सक्षम कइले बानी, पृष्ठ के पुनः लोड करीं आ पुनः प्रयास करीं।", + "badretype": "रउआँ जौन गुप्तशब्द डालत बानी उ मेल नइखे खात।", + "usernameinprogress": "एही प्रयोगकर्तानाँव खातिर खाता खोले के काम पहिलहीं चालू बा।\nइंतजार करीं।", + "userexists": "लिखल गइल प्रयोगकर्तानाँव पहिले से प्रयोग में बा। कौनों दूसर नाम बीछीं।", + "loginerror": "खाता प्रवेश में खराबी", + "createacct-error": "खाता बनावे में खराबी", + "createaccounterror": "ई खाता ना बन पावल: $1", + "nocookiesnew": "प्रयोगकर्ता खाता त बन गइल, बाकी रउआ प्रवेश नइखीं भईल।\n{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकी सब के प्रयोग करे ला।\nराउर कुकीज असक्षम बा।\nकुकीज सक्षम करीं, एकरा बाद आपन नया प्रयोगकर्तानाँव आ गुप्तशब्द के साथ प्रवेश करीं।", + "nocookieslogin": "{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकी सभ के प्रयोग करेला।\nराउर कुकीज असक्षम बा।\nकृपया कुकी के सक्षम करीं आ फिर से कोशिश करीं", + "nocookiesfornew": "स्रोत के पुष्टि ना हो पावे के कारण इ खाता ना बनावलल गइल। \nसुनिश्चित करीं कि रउआँ कुकीज सक्षम कइले बानी, पन्ना दोबारा लोड करीं आ फिर से कोसिस करीं।", "createacct-loginerror": "खाता बनावल सफल भइल बाकी रउआँ अपने-आप लॉगिन ना हो पवलीं। [[Special:UserLogin|मैनुअल लॉगिन]] करीं।", - "noname": "रउआ उपयुक्त प्रयोगकर्ता नाम नईखीं निर्दिष्ट कईले।", - "loginsuccesstitle": "लॉगिन पूरा", - "loginsuccess": "''' \"$1\" के रुप में रउआ {{SITENAME}} में अब प्रवेश कर चुकल बानी।'''", - "nosuchuser": "\"$1\" नाँव के कौनो प्रयोगकर्ता नइखन।\nप्रयोगकर्ता नाम संवेदनशील मामला बा।\nशब्द आ इस्पेलिंग के जाँच करीं, या [[Special:CreateAccount|एगो नया खाता बनाईं]]।", - "nosuchusershort": "ई नाम से कौनो प्रयोगकर्ता नईखन \"$1\".\nआपन शब्द-वर्तनी के जाँच करीं।", - "nouserspecified": "रउआ एगो प्रयोगकर्ता नाम निर्दिष्ट करे के बा।", - "login-userblocked": "ई प्रयोगकर्ता के खाता निष्क्रिय हो चुकल बा। प्रवेश के आज्ञा नईखे।", - "wrongpassword": "गलत गुप्त-शब्द डलले बानी।\nकृपया फिर से कोशिश करीं।", - "wrongpasswordempty": "गुप्त-शब्द खाली बा। कृपया फिर से कोशिश करीं।", - "passwordtooshort": "गुप्त-शब्द कम से कम {{PLURAL:$1|1 अक्षर|$1 अक्षर}} के होवे के चाहीं।", - "passwordtoolong": "गुप्त-शब्द {{PLURAL:$1|$1 अक्षर}} से अधिक लमहर नइखे हो सकत।", - "passwordtoopopular": "अक्सरहा बीछल जाए वाला पासवर्ड ना इस्तेमाल होखी। कौनों अउरी खास अलग टाइप के पासवर्ड चुनीं।", - "password-name-match": "राउर गुप्त-शब्द राउर प्रयोगकर्ता नाम से अलग होवे के चाहीं।", - "password-login-forbidden": "इस सदस्यनाम आ गुप्तशब्द के प्रयोग वर्जित बा।", + "noname": "रउआ बैध प्रयोगकर्तानाँव नइखीं दिहले।", + "loginsuccesstitle": "खाता में प्रवेश हो गइल", + "loginsuccess": "''' \"$1\" के रुप में रउआँ {{SITENAME}} में अब प्रवेश कर चुकल बानी।'''", + "nosuchuser": "\"$1\" नाँव के कौनो प्रयोगकर्ता नइखन।\nप्रयोगकर्तानाँव संवेदनशील मामला बा।\nशब्द आ इस्पेलिंग के जाँच करीं, या [[Special:CreateAccount|एगो नया खाता बनाईं]]।", + "nosuchusershort": "\"$1\" नाँव के कौनो प्रयोगकर्ता नइखन।\nआपन इस्पेलिंग (हिज्जे) जाँचीं।", + "nouserspecified": "एगो प्रयोगकर्तानाँव देवे के परी।", + "login-userblocked": "ए प्रयोगकर्ता के खाता निष्क्रिय हो चुकल बा। प्रवेश के आज्ञा नईखे।", + "wrongpassword": "गलत गुप्तशब्द डलले बानी।\nकृपया फिर से कोसिस करीं।", + "wrongpasswordempty": "गुप्तशब्द खाली बा। कृपया फिर से कोसिस करीं।", + "passwordtooshort": "गुप्तशब्द कम से कम {{PLURAL:$1|1 अक्षर|$1 अक्षर}} के होवे के चाहीं।", + "passwordtoolong": "गुप्तशब्द {{PLURAL:$1|$1 अक्षर}} से लमहर ना चाहीं।", + "passwordtoopopular": "अक्सरहा बीछल जाए वाला गुप्तशब्द ना इस्तेमाल हो सके ला। कौनों अउरी खास अलग किसिम के गुप्तशब्द चुनीं।", + "password-name-match": "राउर गुप्तशब्द राउर प्रयोगकर्तानाँव से अलग होखे के चाहीं।", + "password-login-forbidden": "इस प्रयोगकर्तानाँव आ गुप्तशब्द के प्रयोग वर्जित बा।", "mailmypassword": "गुप्तशब्द रिसेट करीं", - "passwordremindertitle": "{{SITENAME}} खातिर नया अस्थायी गुप्त-शब्द", - "passwordremindertext": "केहु (शायद रउए, $1 आइ॰पी पता से) {{SITENAME}} ($4) पर प्रयोग खातिर नया गुप्तशब्द के निवेदन कईले बानी। सदस्य \"$2\" खातिर एगो अस्थायी गुप्तशब्द बना दिहल गईल बा, आ ई अभी \"$3\" बा। यदि ई राउरे आशय रहल, त अब रउआ खाता प्रवेश खातिर एगो नया गुप्तशब्द चुने के पड़ी।\nराउर अस्थायी गुप्तशब्द के अवधि {{PLURAL:$5|एक दिन|$5 दिनं}} में समाप्त हो जाई।\n\nयदि इ निवेदन केहु अउर कइले रहल, या रउआ आपन पुरान गुप्तशब्द अब नइखी बदले के चाहत काहे कि रउआ राउर पुरनका गुप्तशब्द के स्मरण हो आइल बा, त रउआ इ संदेश के अनदेखा कर सकत बानी, आ आपन पुरान गुप्तशब्द के प्रयोग पहिले हि जइसन कर सकत बानी।", - "noemail": "\"$1\" सदस्य खातिर कउनो भी ई-मेल पता दर्ज नइखे करल गइल।", - "noemailcreate": "रउआ एगो जायज ई-मेल पता उपलब्ध करावे के पड़ी।", - "passwordsent": "\"$1\" के ई-मेल पता पर एगो नया गुप्तशब्द भेज दिहल गइल बा।\nई-मेल पावे के बाद कृपया दुबारा खाता में प्रवेश करब।", - "blocked-mailpassword": "राउर आइपी पता के संपादन करे से रोक दिहल गइल बा। दुरुपयोग रोके खातिर, ए आइपी से पासवर्ड रिकवरी के अनुमति नइखे।", - "eauthentsent": "दर्ज करावल गइल ई-मेल पता पर एगो पुष्टिकरण ई-मेल भेज दिहल गइल बा।\nउ खाता पर कौनो दुसर ईमेल भेजल जाओ उ से पहिले, रउआ भेजल गईल ई-मेल पर दिहल गइल निर्देश के अनुसरण कर के ई-मेल पता के पुष्टिकरण करावे के पड़ी ताकि पता चले की सही में उ राउरे खाता ह।", - "throttled-mailpassword": "पिछला {{PLURAL:$1|एक घंटा|$1 घंटा}} के अंदर एगो गुप्तशब्द पुनर्स्थापन ई-मेल भेजल जा चुकल बा।\nदुरुपयोग से बचावे खातिर {{PLURAL:$1|एक घंटा|$1 घंटा}} में सिर्फ एगो गुप्तशब्द पुनर्स्थापन ई-मेल भेजल जाई।", - "mailerror": "ई-मेल भेजे में त्रुटि: $1", + "passwordremindertitle": "{{SITENAME}} खातिर नया अस्थायी गुप्तशब्द", + "passwordremindertext": "केहू (शायद रउए, $1 आइपी पता से) {{SITENAME}} ($4) पर प्रयोग खातिर नया गुप्तशब्द के निवेदन कइले बा। प्रयोगकर्ता \"$2\" खातिर एगो अस्थायी गुप्तशब्द बना दिहल गइल बा, आ ई \"$3\" बा। यदि ई रउवें चाहत रहलीं, त अब रउआँ के खाता में प्रवेश क के एगो नया गुप्तशब्द चुने के पड़ी।\nराउर अस्थायी गुप्तशब्द के अवधि {{PLURAL:$5|एक दिन|$5 दिन}} में खतम हो जाई।\n\nयदि ई निवेदन केहु अउर कइले रहल, या रउआँ के आपन पुरनका गुप्तशब्द इयाद आ गइल बा आ बदलाव नइखीं चाहत, त रउआँ ए सनेसा के अनदेखा कर सकत बानी, आ आपन पुरनका गुप्तशब्द के प्रयोग पहिले नियर कर सकत बानी।", + "noemail": "\"$1\" प्रयोगकर्ता खातिर कौनों ईमेल पता रिकार्ड में नइखे।", + "noemailcreate": "रउआँ के एगो जायज ईमेल पता देवे के पड़ी।", + "passwordsent": "\"$1\" के ईमेल पता पर एगो नया गुप्तशब्द भेज दिहल गइल बा।\nईमेल पावे के बाद कृपया दुबारा खाता में प्रवेश करीं।", + "blocked-mailpassword": "राउर आइपी पता के संपादन करे से रोक दिहल गइल बा। दुरुपयोग रोके खातिर, ए आइपी से गुप्तशब्द दोबारा हासिल करे के इजाजत नइखे।", + "eauthentsent": "दर्ज करावल गइल ईमेल पता पर एगो पुष्टिकरण ईमेल भेज दिहल गइल बा।\nउ खाता पर कौनो दूसर ईमेल भेजल जाव ओ से पहिले, रउआँ भेजल गइल ईमेल पर दिहल गइल निर्देश के अनुसार ईमेल पता के पुष्टिकरण करावे के पड़ी ताकि पता चले की सही में ऊ राउरे खाता हऽ।", + "throttled-mailpassword": "पिछला {{PLURAL:$1|एक घंटा|$1 घंटा}} के अंदर एगो गुप्तशब्द बदलाव ईमेल भेजल जा चुकल बा।\nदुरुपयोग से बचावे खातिर {{PLURAL:$1|एक घंटा|$1 घंटा}} में सिर्फ एगो गुप्तशब्द बदलाव ईमेल भेजल जाई।", + "mailerror": "ईमेल भेजे में गड़बड़ी: $1", "acct_creation_throttle_hit": "राउर आइपी पता से आइल आगंतुक लोग पिछला $2 में एह विकि पर {{PLURAL:$1|एक ठो खाता|$1 खाता}} बना चुकल बा जवन एह समयअवधि में अधिकतम सीमा बा।\nएही कारण, एह आइपी पता के इस्तेमाल करे वाला आगंतुक अब कौनों अउरी खाता एह समय नइखें बना सकत।", - "emailauthenticated": "$2 के $3 पर राउर ई-मेल पता के पुष्टीकरण हो चुकल बा।", - "emailnotauthenticated": "राउर ई-मेल पता के अभी तक प्रमाणिकरण नइखे भईल।\nनिम्नलिखित कउनो भी सुविधा खातिर रउआ के कौनो भी ई-मेल ना भेजल जाई।", - "noemailprefs": "इ सुविधा के प्रयोग करे खातिर आपन वरियता में एगो ई-मेल पता दिहीं।", - "emailconfirmlink": "अपना ई-मेल पता कन्फर्म करीं", - "invalidemailaddress": "राउर ई-मेल पता स्वीकार करल नइखे जा सकत काहे कि ई-मेल के जउन रुप दिखाई दे रहल बा उ गलत लागत बा।\nकृपया एगो सहि ई-मेल पता उपलब्ध कराईं या उ जगह के खाली छोड़ दिहीं।", - "cannotchangeemail": "इ विकी पर ई-मेल पता बदलल नईखे जा सकत।", - "emaildisabled": "इ साईट से ई-मेल नईखे भेजल जा सकत।", - "accountcreated": "खाता बनावल गईल", - "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|वार्ता]]) खातिर खाता निर्मित कर दिहल गईल बा।", + "emailauthenticated": "$2 के $3 पर राउर ईमेल पता के पुष्टीकरण हो चुकल बा।", + "emailnotauthenticated": "राउर ईमेल पता के अभी तक प्रमाणिकरण नइखे भइल।\nनीचे लिखल कौनों भी सुविधा खातिर रउआ के कौनो भी ईमेल ना भेजल जाई।", + "noemailprefs": "ए सुविधा के प्रयोग करे खातिर आपन सेटिंग में एगो ईमेल पता देईं।", + "emailconfirmlink": "अपना ईमेल पता के पुष्टी करीं", + "invalidemailaddress": "राउर ईमेल पता अबैध फॉरमैट में बुझात बा आ स्वीकार नइखे हो सकत।\nसही-फॉरमैट में ईमेल पता देईं या जगह के खाली छोड़ देईं।", + "cannotchangeemail": "ए विकी पर ईमेल पता ना बदलल जा सकत बा।", + "emaildisabled": "इ साइट से ईमेल नइखे भेजल जा सकत।", + "accountcreated": "खाता बनावल गइल", + "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|वार्ता]]) खातिर खाता बना दिहल गइल।", "createaccount-title": "{{SITENAME}} खातिर खाता बनाईं", - "createaccount-text": "राउर ई-मेल पता खातिर {{SITENAME}} ($4) पर \"$2\" सदस्य नाम से \"$3\" गुप्तशब्द (पासवर्ड) सहित खाता खोलले बानी। रउआ खाता में प्रवेश कर के आपन गुप्तशब्द (पासवर्ड) तुरंत बदल लेवे के चाहीं।\n\nयदि इ खाता गलती से खोलल गईल बा, त रउआ इ संदेश के अनदेखा कर सकत बानी।", - "login-throttled": "रउआ हाले में कईयन बार खाता में प्रवेश करे के कोशिश कर चुकल बानी।\nकृपया $1 प्रतिक्षा करला के बाद फिर से प्रयास करब।", - "login-abort-generic": "राउर लॉगिन बिफल रहल - रद्द कइल गइल", - "login-migrated-generic": "आप के खाता माइग्रेट हो चुकल बा अउर आप के सदस्यनाम इ विकी पर अब मौजूद नइखे।", + "createaccount-text": "राउर ईमेल पता खातिर {{SITENAME}} ($4) पर \"$2\" प्रयोगकर्तानाँव से \"$3\" गुप्तशब्द के साथ केहू खाता खोलले बा।\nरउआँ के खाता में प्रवेश कर के आपन गुप्तशब्द तुरंत बदल लेवे के चाहीं।\n\nयदि ई खाता गलती से खोलल गइल बा, त रउआ ए सनेसा के अनदेखा कर सकत बानी।", + "login-throttled": "रउआ हाले में कइयन बेर खाता में प्रवेश करे के कोशिश क चुकल बानी।\nकृपया $1 इंतजार के बाद फिर से कोसिस करब।", + "login-abort-generic": "राउर खाता में प्रवेश बिफल रहल - रद्द कइल गइल", + "login-migrated-generic": "आप के खाता माइग्रेट हो चुकल बा अउर आप के प्रयोगकर्तानाँव ए विकी पर अब मौजूद नइखे।", "loginlanguagelabel": "भाषा: $1", - "suspicious-userlogout": "राउर खाता से बाहर जाये के अनुरोध अस्वीकृत कर दिहल गइल बा काहे कि अइसन लग रहल बा कि इ कउनो खराब ब्राउज़र या कैश करे वाली प्रॉक्सी द्वारा भेजल गईल रहल।", - "createacct-another-realname-tip": "असली नाम वैकल्पिक बा।\nयदि रउआ इ के उपलब्ध करावे के चुनत बानी त, एकर प्रयोग सदस्य के ओकरा काम के अधिकार देवे खातिर होखी।", + "suspicious-userlogout": "राउर खाता से बाहर जाये के अनुरोध अस्वीकृत कर दिहल गइल बा काहे कि अइसन बुझाता कि ई कौनों खराब ब्राउजर या कशे करे वाली प्रॉक्सी द्वारा भेजल गइल रहल।", + "createacct-another-realname-tip": "असली नाम वैकल्पिक बा।\nअगर रउआँ असली नाँव देवे के बिकल्प चुनब, एकर इस्तेमाल प्रयोगकर्ता के ओकरा काम के श्रेय देवे खातिर होखी।", "pt-login": "खाता में प्रवेश", - "pt-login-button": "लॉग इन", - "pt-login-continue-button": "लॉगिन जारी राखीं", + "pt-login-button": "खाता में प्रवेश", + "pt-login-continue-button": "खाता में प्रवेश जारी राखीं", "pt-createaccount": "खाता बनाईं", - "pt-userlogout": "लॉग आउट", - "php-mail-error-unknown": "PHP के mail() फ़ंक्शन में अज्ञात त्रुटि बा।", - "user-mail-no-addy": "बिना कउनो ई-मेल पता के ई-मेल भेजे के प्रयत्न भईल बा।", - "user-mail-no-body": "एगो खाली अथवा बहुत छोट ई-मेल भेजे के प्रयत्न भईल बा।", - "changepassword": "गुप्त शब्द बदलीं", - "resetpass_announce": "लॉग इन सम्पूर्ण करे खातिर रउआ एगो नया पासवर्ड देवे के होई।", + "pt-userlogout": "खाता से बाहर", + "php-mail-error-unknown": "PHP के mail() फंक्शन में नामालूम गड़बड़ी बा।", + "user-mail-no-addy": "बिना कौनो ईमेल पता के ईमेल भेजे के कोसिस भइल बा।", + "user-mail-no-body": "एगो खाली या बहुत छोट ईमेल भेजे के कोसिस भइल बा।", + "changepassword": "गुप्तशब्द बदलीं", + "resetpass_announce": "खाता में प्रवेश पूरा करे खातिर रउआँ के एगो नया पासवर्ड देवे के पड़ी।", "resetpass_header": "खाता के गुप्तशब्द बदलीं", - "oldpassword": "पुराना गुप्त-शब्द:", - "newpassword": "नया गुप्त-शब्द:", - "retypenew": "नया गुप्त-शब्द पुन: डालीं:", + "oldpassword": "पुरान गुप्तशब्द:", + "newpassword": "नया गुप्तशब्द:", + "retypenew": "नया गुप्तशब्द फिर डालीं:", "resetpass_submit": "गुप्तशब्द बनाईं आ खाता में प्रवेश करीं", - "changepassword-success": "राउर पासवर्ड बदल दिहल गइल बा!", - "changepassword-throttled": "रउआ हाले में कईयन बार खाता में प्रवेश करे के कोशिश कर चुकल बानी।\nकृपया $1 प्रतिक्षा करला के बाद फिर से प्रयास करब।", + "changepassword-success": "राउर गुप्तशब्द बदल दिहल गइल बा!", + "changepassword-throttled": "रउआँ हाले में कइयन बेर खाता में प्रवेश करे के कोसिस क चुकल बानी।\nकृपया $1 इंतजार के बाद फिर से कोसिस करब।", "botpasswords": "बॉट पासवर्ड", "botpasswords-summary": "बॉट पासवर्ड खाता के मुख्य प्रवेश-पहिचान-जानकारी के बिना, सीधे एपीआई के माध्यम से खाता ले पहुँच देवे लें। बॉट पासवर्ड दे के खाता में प्रवेश के बाद खाता के प्रयोगकर्ता अधिकार कुछ सीमित हो सकेला।\n\nअगर आपके ई नइखे मालूम कि ई करे के आपके का जरूरत बा, साइद आपके ई ना करे के चाहीं। केहू भी रउवाँ से कबो ई पासवर्ड जनरेट करे के ना कही न आपसे ई पासवर्ड माँगी।", "botpasswords-disabled": "बॉट पासवर्ड अक्षम कइल गइल बा।", @@ -545,29 +545,29 @@ "botpasswords-deleted-body": "प्रयोगकर्ता \"$2\" के बॉट नाँव \"$1\" खातिर बॉट पासवर्ड मिटावल गइल।", "resetpass_forbidden": "गुप्तशब्द बदलल नइखे जा सकत", "resetpass_forbidden-reason": "गुप्तशब्द बदलल नइखे जा सकत:$1", - "resetpass-no-info": "इ पन्ना के सिधे प्रयोग करे खातिर रउआ पहिले खाता में प्रवेश करे के पड़ी।", - "resetpass-submit-loggedin": "गुप्त शब्द बदलीं", + "resetpass-no-info": "इ पन्ना के सिधे प्रयोग करे खातिर रउआँ के पहिले खाता में प्रवेश करे के पड़ी।", + "resetpass-submit-loggedin": "गुप्तशब्द बदलीं", "resetpass-submit-cancel": "रद्द करीं", "resetpass-wrong-oldpass": "अबैध अस्थायी या वर्तमान गुप्तशब्द।\nरउआ पहिलहीं आपन गुप्तशब्द बदल चुकल बानी, या रउआ एगो अस्थायी गुप्तशब्द के अनुरोध कइले हो सकत बानी।", "resetpass-recycled": "रीसेट करे खातिर नया पासवर्ड में कृपया आपन वर्तमान पासवर्ड के अलावा कौनो अन्य पासवर्ड के प्रयोग करीं।", - "resetpass-temp-emailed": "अस्थाई ईमेल कोड के द्वारा रउआ लॉग इन भइल बानी।\nलॉग इन पूरा करे खातिर, रउआ एगो नया पासवर्ड सेट करे के पड़ी:", + "resetpass-temp-emailed": "अस्थाई ईमेल कोड के द्वारा रउआ खाता में प्रवेश कइले बानी।\nखाता में प्रवेश पूरा करे खातिर एगो नया गुप्तशब्द सेट करे के पड़ी:", "resetpass-temp-password": "अस्थायी गुप्तशब्द:", - "resetpass-abort-generic": "कउनो एक्सटेंशन द्वारा गुप्तशब्द में बदलाव रोक दिहल गईल बा।", - "resetpass-expired": "राउर पासवर्ड की वैधता अवधि समाप्त हो चुकल बा। कृपया लॉग इन करे खातिर एगो नया पासवर्ड सेट करीं।", - "resetpass-expired-soft": "राउर गुप्तशब्द अमान्य हो चुकल बा इ के पुनः स्थापित करे के पड़ी। कृपया अभी एगो नया गुप्तशब्द चुनीं या \"{{int:authprovider-resetpass-skip-label}}\" पर बाद में पुनः स्थापित कर सकत बानी।", - "resetpass-validity-soft": "राउर पासवर्ड मान्य नईखे: $1 \n\nकृपया अब एक नया पासवर्ड चुनीं, या उ के बाद में पुनर्स्थापित करे खातिर \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करीं।", - "passwordreset": "गुप्तशब्द (पासवर्ड) रिसेट करीं", - "passwordreset-text-one": "आपन गुप्तशब्द के पुनर्स्थापित करे खातिर इ फॉर्म भरीं।", - "passwordreset-text-many": "{{PLURAL:$1|ईमेल द्वारा अस्थाई पासवर्ड पावे खातिर निम्न में से कउनो एगो स्थान भरीं।}}", - "passwordreset-disabled": "इ विकी पर पासवर्ड पुनर्स्थापन अक्षम बा।", - "passwordreset-emaildisabled": "इ विकि पर ई-मेल सुविधा अक्षम कर दिहल गईल बा।", - "passwordreset-username": "प्रयोगकर्ता नाम", + "resetpass-abort-generic": "कउनो एक्सटेंशन द्वारा गुप्तशब्द में बदलाव रोक दिहल गइल बा।", + "resetpass-expired": "राउर गुप्तशब्द के वैधता समय खतम हो चुकल बा। खाता में प्रवेश करे खातिर एगो नया गुप्तशब्द सेट करीं।", + "resetpass-expired-soft": "राउर गुप्तशब्द के समय खतम हो चुकल बा आ बदले के जरूरत बा। अब्बे नया गुप्तशब्द चुनीं, या बाद में बदले के होखे त क्लिक करीं \"{{int:authprovider-resetpass-skip-label}}\"।", + "resetpass-validity-soft": "राउर गुप्तशब्द मान्य नइखे: $1 \n\nअब एगो नया गुप्तशब्द चुनीं, या \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करीं अगर बाद में बदले के होखे।", + "passwordreset": "गुप्तशब्द रिसेट करीं", + "passwordreset-text-one": "ईमेल से अस्थायी गुप्तशब्द पावे खातिर ई फारम भरीं।", + "passwordreset-text-many": "{{PLURAL:$1|ईमेल द्वारा अस्थाई पासवर्ड पावे खातिर नीचे के कौनो एगो स्थान भरीं।}}", + "passwordreset-disabled": "ए विकि पर गुप्तशब्द बदलल अक्षम कइल गइल बा।", + "passwordreset-emaildisabled": "ए विकि पर ईमेल सुबिधा अक्षम कइल गइल बा।", + "passwordreset-username": "प्रयोगकर्तानाँव:", "passwordreset-domain": "डोमेन:", - "passwordreset-email": "ई-मेल पता:", + "passwordreset-email": "ईमेल पता:", "passwordreset-emailtitle": "{{SITENAME}} पर खाता विवरण", - "passwordreset-emailtext-ip": "केहु (शायद रउए, $1 आइ॰पी पता से) {{SITENAME}} ($4) पर आपन {{PLURAL:$3|गुप्तशब्द}} के रीसेट करे के अनुरोध कईले बानी। इ ई-मेल पता से निम्न {{PLURAL:$3|खाता जुड़ल बा}}:\n\n$2\n\n{{PLURAL:$3|इ}} अस्थायी गुप्तशब्द {{PLURAL:$5|एक दिन|$5 दिन}} के बाद काम ना करी। रउआ खाता में प्रवेश करके एगो नया गुप्तशब्द अभी चुन लेवे के चाहीं। यदि इ अनुरोध केहु अउर कइले बा, या फिर रउआ आपन मूल गुप्तशब्द याद आ गईल बा, अउर आप {{PLURAL:$3|आपन}} गुप्तशब्द नइखी बदले के चाहत त, रउआ इ संदेश के अनदेखा कर के आपन पुरानका गुप्तशब्द के प्रयोग जारी रख सकत बानी।", - "passwordreset-emailtext-user": "{{SITENAME}} ($4) पर सदस्य $1 राउर {{PLURAL:$3|खाता}} के गुप्तशब्द के पुनर्स्थापित करे के अनुरोध कइले बानी। इ ई-मेल पता से निम्न {{PLURAL:$3|खाता जुड़ल बा}}:\n\n$2\n\n{{PLURAL:$3|इ}} अस्थायी गुप्तशब्द {{PLURAL:$5|एक दिन|$5 दिन}} के बाद काम ना करी।\nरउआ खाता में प्रवेश करके एगो नया गुप्तशब्द अभीये चुन लेवे के चाहीं। यदि इ अनुरोध केहु अउर कइले बा, या फिर रउआ आपन मूल गुप्तशब्द याद आ गईल बा, अउर रउआ {{PLURAL:$3|आपन}} गुप्तशब्द नईखीं बदले के चाहत त, रउआ इ संदेश के अनदेखा कर के आपन पुरनका गुप्तशब्द के प्रयोग जारी रख सकत बानीं।", - "passwordreset-emailelement": "सदस्यनाम: \n$1\n\nअस्थायी गुप्तशब्द: \n$2", + "passwordreset-emailtext-ip": "केहु (शायद रउए, $1 आइपी पता से) {{SITENAME}} ($4) पर आपन {{PLURAL:$3|गुप्तशब्द}} के रीसेट करे के अनुरोध कइले बा। ए ईमेल पता से नीचे दिहल {{PLURAL:$3|खाता जुड़ल बा}}:\n\n$2\n\n{{PLURAL:$3|इ}} अस्थायी गुप्तशब्द {{PLURAL:$5|एक दिन|$5 दिन}} के बाद काम ना करी। रउआँ के खाता में प्रवेश क के एगो नया गुप्तशब्द अब्बे चुन लेवे के चाहीं। यदि ई अनुरोध केहु अउर कइले बा, या फिर रउआँ के आपन मूल गुप्तशब्द इयाद आ गइल बा, आ आप {{PLURAL:$3|आपन}} गुप्तशब्द नइखीं बदलल चाहत त ए सनेसा के अनदेखा क के आपन पुरानका गुप्तशब्द के प्रयोग जारी रख सकत बानी।", + "passwordreset-emailtext-user": "{{SITENAME}} ($4) पर सदस्य $1 राउर {{PLURAL:$3|खाता}} के गुप्तशब्द के पुनर्स्थापित करे के अनुरोध कइले बानी। ए ईमेल पता से नीचे दिहल {{PLURAL:$3|खाता जुड़ल बा}}:\n\n$2\n\n{{PLURAL:$3|इ}} अस्थायी गुप्तशब्द {{PLURAL:$5|एक दिन|$5 दिन}} के बाद काम ना करी।\nरउआँ के खाता में प्रवेश करके एगो नया गुप्तशब्द अब्बे चुन लेवे के चाहीं। यदि ई अनुरोध केहु अउर कइले बा, या फिर रउआँ के आपन मूल गुप्तशब्द इयाद आ गइल बा, आ रउआँ {{PLURAL:$3|आपन}} गुप्तशब्द नइखीं बदलल चाहत त ए सनेसा के अनदेखा क के आपन पुरनका गुप्तशब्द के प्रयोग जारी रख सकत बानीं।", + "passwordreset-emailelement": "प्रयोगकर्तानाँव: \n$1\n\nअस्थायी गुप्तशब्द: \n$2", "passwordreset-emailsentemail": "अगर दिहल गइल ईमेल पता आपके खाता के साथ जुड़ल होखी, गुप्तशब्द दुबारा सेट करे खातिर एक ठो ईमेल भेज दिहल जाई।", "passwordreset-emailsentusername": "अगर एह प्रयोगकर्तानाँव के साथ कौनों ईमेल जुड़ल होखी, गुप्तशब्द बदले खातिर एक ठो ईमेल भेज दिहल जाई।", "passwordreset-nocaller": "एक ठो काल करे वाला दिहल जरूरी बाटे", @@ -579,19 +579,19 @@ "changeemail-header": "आपन ईमेल पता बदले खातिर ई फार्म भरीं। अगर आप अपना खाता से जुड़ल ईमेल हटावल चाहत बानी, तब नया ईमेल वाला बिकल्प के फार्म में खाली छोड़ देईं।", "changeemail-no-info": "इ पन्ना के सिधे प्रयोग करे खातिर रउआ पहिले खाता में प्रवेश करे के पड़ी।", "changeemail-oldemail": "वर्तमान ई-मेल पता:", - "changeemail-newemail": "नया ई-मेल पता:", + "changeemail-newemail": "नया ईमेल पता:", "changeemail-newemail-help": "ई बिकल्प के खाली तबे छोड़ल जाय जब आप आपन ईमेल खाता से हटावल चाहत होखीं। एकरा बाद आपन भुलाइल पासवर्ड बदले खातिर ईमेल ना माँग पाइब, न एह विकि से कौनों ईमेल आपके भेजल जा पाई अगर आप आपन ईमेल पता इहाँ से हटा देइब।", - "changeemail-none": "(कउनो नाहीं)", + "changeemail-none": "(कौनो ना)", "changeemail-password": "राउर {{SITENAME}} गुप्तशब्द:", - "changeemail-submit": "ई-मेल बदलीं", - "changeemail-throttled": "रउआ हाले में कईयन बार खाता में प्रवेश करे के कोशिश कर चुकल बानी।\nकृपया $1 प्रतिक्षा करला के बाद फिर से प्रयास करब।", + "changeemail-submit": "ईमेल बदलीं", + "changeemail-throttled": "रउआँ हाले में कइयन बेर खाता में प्रवेश करे के कोसिस क चुकल बानी।\nकृपया $1 इंतजार के बाद फिर से कोसिस करब।", "changeemail-nochange": "इहाँ एक ठो दूसर ईमेल भरीं।", "resettokens": "टोकन रीसेट करीं", - "resettokens-text": "जौन टोकन राउर खाता से सम्बद्ध कुछ विशिष्ट व्यक्तिगत जानकारी प्रदान करेला, आप उ के अहिजा रीसेट कर सकत बानी।\n\nयदि रउआ ई के गलती से केहू के दिखा देले बानी या फिर राउर खाता हैक हो गईल बा त रउआ ई के रीसेट कर देवे के चाहीं।", + "resettokens-text": "जौन टोकन राउर खाता से सम्बद्ध कुछ विशिष्ट व्यक्तिगत जानकारी प्रदान करेला, आप इनहन के एहिजा रीसेट कर सकत बानी।\n\nयदि रउआँ एकरा के गलती से केहू के देखा देले बानी या फिर राउर खाता हैक हो गइल बा त एकरा के रीसेट कर देवे के चाहीं।", "resettokens-no-tokens": "रीसेट करे खातिर कउनो टोकन नइखे।", "resettokens-tokens": "टोकन:", - "resettokens-token-label": "$1 (वर्तमान मूल्य: $2)", - "resettokens-watchlist-token": "[[Special:Watchlist|आपके ध्यानसूची के पन्नन में बदलावसभ]] के वेब फ़ीड (Atom/RSS) हेतु टोकन", + "resettokens-token-label": "$1 (वर्तमान वैल्यू: $2)", + "resettokens-watchlist-token": "[[Special:Watchlist|आपके धियानसूची के पन्नन में बदलावसभ]] के वेब फीड (एटम/आरऍसऍस) खातिर टोकन", "resettokens-done": "टोकन रीसेट हो चुकल बा।", "resettokens-resetbutton": "चुनल गइल टोकन रीसेट करीं", "bold_sample": "मोट अच्छर में", @@ -612,7 +612,7 @@ "media_tip": "फाइल कड़ी", "sig_tip": "समय मोहर की संघे राउर दस्खत", "hr_tip": "पड़ी लकीर (कम प्रयोग करीं)", - "summary": "छोट विवरण (सारांश):", + "summary": "सारांश:", "subject": "बिसय:", "minoredit": "छोट परिवर्तन", "watchthis": "धियानसूची में डालीं", @@ -620,20 +620,20 @@ "savechanges": "बदलाव सहेजीं", "publishpage": "पन्ना प्रकाशित करीं", "publishchanges": "बदलाव प्रकाशित करीं", - "preview": "पूर्वावलोकन", + "preview": "झलक", "showpreview": "झलक देखीं", "showdiff": "बदलाव देखीं", - "blankarticle": "चेतावनी: आप एगो खाली पन्ना के बनावे जा रहल बानी।\nयदि आप \"{{int:savearticle}}\" के फेर से दबायेब त पन्ना बिना कउनो सामग्री के बन जाई।", - "anoneditwarning": "चेतावनी: रउआ आपन खाता में प्रवेश नइखीं कइले। अगर रउआ कौनों बदलाव करत बानी त राउर आईपी पता दर्ज होई। अगर रउआ [$1 लॉग इन] या [$2 नया खाता बनाइब] त, अउरी सुबिधा सब की संघे राउर संपादन के श्रेय भी राउर सदस्य-नाँव से जुड़ जाई!", - "anonpreviewwarning": "''रउआ खाता में प्रवेश नईखीं भईल। सुरक्षित करेब त ई पन्ना के सम्पादन इतिहास पर राउर आई पी पता दर्ज हो जाई।\"", - "missingsummary": "'''स्मरणपत्र:'''रउआ एगो सारांश के सम्पादन नईखीं प्रदान कईले। अगर रउआ \"फिर से सुरक्षित करीं\" पर क्लिक करेब, त राउर सम्पादन बिना एगो सारांश के सुरक्षित हो जाई।", - "selfredirect": "चेतावनी: आप खुद के इ पन्ना पर पुनः निर्देशित कर रहल बानी।\nआप अनुप्रेषित खातिर गलत लक्ष्य निर्दिष्ट हो सकत बानी, या आप के द्वारा गलत पन्ना के संपादन हो सकत बा।\nआप यदि फेर से \"{{int:savearticle}}\" क्लिक करत बानी त, पुन: निर्देषण ओइसहु बनावल जाई।", - "missingcommenttext": "कृपया निचे एगो टिप्पणी करीं।", + "blankarticle": "चेतावनी: आप एगो खाली पन्ना बनावे जा रहल बानी।\nयदि आप \"{{int:savearticle}}\" के फेर से दबायेब त पन्ना बिना कउनो सामग्री के बन जाई।", + "anoneditwarning": "चेतावनी: रउआँ आपन खाता में प्रवेश नइखीं कइले। अगर रउआँ कौनों बदलाव करब त राउर आईपी पता सभके लउकी। अगर रउआ [$1 खाता में प्रवेश करब] या [$2 नया खाता बनाइब] त, अउरी सुबिधा सब की संघे राउर संपादन के श्रेय भी राउर प्रयोगकर्तानाँव के मिली!", + "anonpreviewwarning": "''रउआँ खाता में प्रवेश नइखीं भइल। सहेजब तब ए पन्ना के संपादन इतिहास में राउर आईपी पता दर्ज हो जाई।\"", + "missingsummary": "'''याद दियावल जात बा:'''रउआँ एगो संपादन सारांश नइखीं दिहले। अगर फिर \"{{int:savearticle}}\" पर क्लिक करब, त राउर संपादन एकरे बिना सहेजा जाई।", + "selfredirect": "चेतावनी: आप ई पन्ना के खुदे एही पर अनुप्रेषण क रहल बानी।\nया त आप अनुप्रेषण खातिर गलत लक्ष्य देत बानी, या आप गलत पन्ना के संपादन करत बानी।\nएक बेर अउरी \"{{int:savearticle}}\" क्लिक करब त, ओइसहूँ ई अनुप्रेषण बना दिहल जाई।", + "missingcommenttext": "नीचे एगो टिप्पणी भरीं।", "missingcommentheader": "'''याद दियावल जात बा:''' रउआँ एह कमेंट खातिर कौनों बिसय नइखीं दिहले। अगर आप \"{{int:savearticle}}\" पर क्लिक करब तब राउर संपादन एकरे बिना सहेजा जाई।", - "summary-preview": "सारांश पूर्वावलोकन:", + "summary-preview": "सारांश झलक:", "subject-preview": "बिसय के झलक:", - "previewerrortext": "जब आप आपन बदलाव के पुर्वावलोकन देखे खातिर प्रयास कइनी ह तवने घड़ी एगो त्रुटी उत्पन्न हो गइल बा।", - "blockedtitle": "निष्क्रिय प्रयोगकर्ता", + "previewerrortext": "राउर बदलाव के झलक देखावे के कोसिस के समय कुछ गड़बड़ी हो गइल।", + "blockedtitle": "प्रयोगकर्ता रोक दिहल गइल बा", "blockedtext": "'''राउर सदस्यनाम अथवा आइ॰पी पता अवरोधित कर दिहल गईल बा ।'''\n\nअवरोध $1 द्वारा करल गईल रहल।\nअवरोध के कारण बा ''$2''\n\n* अवरोध के आरंभ: $8\n* अवरोध के समाप्ति: $6\n* अवरोधित इकाई: $7\n\nइ अवरोध के बारे में चर्चा करे खातिर रउआ $1 या केहु अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]] से संपर्क कर सकत बानी।\nअगर रउआ [[Special:Preferences|आपन वरीयता]] में वैद्य ई-मेल पता प्रविष्ट कइले होखब तबे 'इ प्रयोक्ता के ई-मेल भेजीं' वाला सुविधा के प्रयोग कर सकत बानी अउर रउआ एकर प्रयोग करे से ना रोकल गईल होखे।\nराउर हाल के आइ॰पी पता $3 ह अउर अवरोध क्रमांक #$5 ह।\nआपन कउनो भी प्रश्न में कृपया इ सब जानकारी भी शामिल करब।", "autoblockedtext": "राउर आइ॰पी पता अपने आप अवरुद्ध हो गईल बा काहे कि एकर प्रयोग केहु अन्य सदस्य द्वारा होत रहल,\nजे $1 द्वारा अवरोधित करल गईल रहलन। \nअवरोध करे के कारण बा:\n\n:''$2''\n\n* अवरोध प्रारंभ: $8\n* अवरोध समाप्ति: $6\n* अवरोधित सदस्य: $7\n\nअवरोध के चर्चा करे खातिर रउआ $1 या केहु अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबंधक]] से संपर्क कर सकत बानी।\n\nकृपया ध्यान रहे कि यदि रउआ \"इ सदस्य के ई-मेल भेजीं\" वाला सुविधा के प्रयोग करे के चाहत बानी त राउर [[Special:Preferences|वरीयता]] में वैद्य ई-मेल पता होखे के चाहीं अउर एकर प्रयोग रउआ खातिर अवरोधित ना भईल होखे।\n\nराउर हाल के आइ॰पी पता $3 ह अउर अवरोध क्रमांक #$5 ह।\nआपन कउनो भी प्रश्न में कृपया इ सब जानकारी शामिल करब।", "systemblockedtext": "राउर खाता या आइपी पता के मीडियाविकि द्वारा ऑटोमेटिक रूप से रोक दिहल गइल बा।\nएकरा खातिर कारण दिहल गइल बा:\n\n\n:$2\n\n* रोक के सुरुआत: $8\n* रोक समाप्त होखी: $6\n* रोक लगावे वाला: $7\n\nराउर वर्तमान आइपी पता $3 बा।\nअगर कौनों सवाल करीं तब ऊपर बतावल सगरी जानकारी देईं।", @@ -867,22 +867,22 @@ "history-title": "''$1'' के संशोधन इतिहास", "difference-title": "\"$1\" की अवतरण में अंतर", "lineno": "लाइन $1:", - "compareselectedversions": "चुनल गईल संशोधन में अन्तर देखीं", - "showhideselectedversions": "चुनल गईल संशोधन दिखाईं/छुपाईं", + "compareselectedversions": "चुनल गइल संशोधन में अंतर देखीं", + "showhideselectedversions": "चुनल गइल संशोधन के दृश्यता बदलीं", "editundo": "वापस लीं", - "diff-multi-sameuser": "(एही सदस्य द्वारा कइल {{PLURAL:$1|बीच के एगो बदलाव|$1 बीच के बदलाव सब}} नइखे देखावल जात)", + "diff-multi-sameuser": "(एही सदस्य द्वारा कइल {{PLURAL:$1|बीच के एगो बदलाव|बीच के $1 बदलाव}} नइखे देखावल जात)", "searchresults": "खोज परिणाम", "searchresults-title": "$1 खातिर खोज परिणाम", - "titlematches": "पन्ना के शिर्षक मिलत बा।", - "textmatches": "पन्ना के पाठ्य मिलत बा", - "notextmatches": "पन्ना के पाठ्य नईखे मिलत", + "titlematches": "पन्ना टाइटिल मिलान", + "textmatches": "पन्ना पाठ मिलान", + "notextmatches": "कौनों पन्ना पाठ मिलान नइखे", "prevn": "पछिला {{PLURAL:$1|$1}}", "nextn": "अगिला {{PLURAL:$1|$1}}", "prev-page": "पिछलका पन्ना", "next-page": "अगला पन्ना", "prevn-title": "पिछला $1 {{PLURAL:$1|परिणाम}}", "nextn-title": "अगिला $1 {{PLURAL:$1|परिणाम}}", - "shown-title": "एक पन्ना पर $1 {{PLURAL:$1|परिणाम}} देखाईं", + "shown-title": "प्रति पन्ना $1 {{PLURAL:$1|परिणाम}} देखाईं", "viewprevnext": "देखीं ($1 {{int:pipe-separator}} $2) ($3)", "searchmenu-exists": "'''इ विकि पर ''[[:$1]]'' नाम से एगो पन्ना उपलब्ध बा'''", "searchmenu-new": " ए विकि पर \"[[:$1]]\" नाँव के पन्ना बनाईं ! {{PLURAL:$2|0=|अपनी खोज से मिलल पन्ना भी देखीं|खोज के परिणाम भी देखीं।}}", @@ -921,8 +921,8 @@ "skin-preview": "पूर्वावलोकन", "datedefault": "वरीयता नईखे", "prefs-user-pages": "सदस्य पन्ना", - "prefs-personal": "सदस्य प्रोफाईल", - "prefs-rc": "तुरंत भइल परिवर्तन", + "prefs-personal": "प्रयोगकर्ता प्रोफाइल", + "prefs-rc": "हाल के बदलाव", "prefs-watchlist": "धियानसूची", "prefs-editwatchlist": "धियानसूची संपादन", "prefs-editwatchlist-label": "अपनी धियानसूची के चीज संपादित करीं:", @@ -934,17 +934,17 @@ "prefs-watchlist-edits": "बिस्तारित धियानसूची में देखावे खातिर अधिकतम बदलाव संख्या:", "prefs-watchlist-edits-max": "अधिकतम संख्या:1000", "prefs-watchlist-token": "धियानसूची टोकन:", - "prefs-misc": "अउरी कुल", - "prefs-resetpass": "पासवर्ड बदलीं", + "prefs-misc": "बिबिध", + "prefs-resetpass": "गुप्तशब्द बदलीं", "prefs-changeemail": "ईमेल पता बदलीं", "prefs-setemail": "ईमेल पता सेट करीं", "prefs-email": "ईमेल बिकल्प", "prefs-rendering": "रंगरूप", - "saveprefs": "सुरक्षित करीं", + "saveprefs": "सहेजीं", "restoreprefs": "सगरी डिफाल्ट सेटिंग पहिले जइसन करीं (सगरी खंड में)", "prefs-editing": "संपादन", "searchresultshead": "खोज", - "stub-threshold-disabled": "निरस्त", + "stub-threshold-disabled": "अक्षम", "recentchangesdays": "हाल में भइल परिवर्तन में देखावे खातिर दिन:", "recentchangesdays-max": "अधिकतम $1{{PLURAL:$1|दिन}}", "recentchangescount": "डिफाल्ट में देखावे खातिर संपादन संख्या:", @@ -977,6 +977,7 @@ "prefs-reset-intro": "रउआँ आपन पसंद बदल के डिफाल्ट करे खातिर ए पन्ना के इस्तेमाल नइखीं कर सकत।\n\nई फिर से वापस ना हो पाई।", "prefs-emailconfirm-label": "ईमेल जाँच:", "youremail": "ईमेल:", + "username": "{{GENDER:$1|प्रयोगकर्तानाँव}}:", "prefs-registration": "रजिस्ट्रेशन के समय:", "yourrealname": "असली नाम", "yourlanguage": "भाषा:", @@ -1337,7 +1338,7 @@ "listusers-desc": "घटत क्रम से सरियाईं", "usereditcount": "$1 {{PLURAL:$1|संपादन|संपादन सभ}}", "newpages": "नया पन्ना", - "newpages-username": "सदस्यनाँव:", + "newpages-username": "प्रयोगकर्तानाँव:", "ancientpages": "पुरान पन्ना", "move": "स्थानांतरण", "movethispage": "एह पन्ना के स्थानांतरण करीं", @@ -1368,6 +1369,7 @@ "trackingcategories-msg": "निगरानी श्रेणी", "trackingcategories-name": "संदेस नाँव", "emailuser": "ई प्रयोगकर्ता के ईमेल करीं", + "emailusername": "प्रयोगकर्तानाँव:", "watchlist": "धियानसूची", "mywatchlist": "धियानसूची", "watch": "धियानसूची में डालीं", diff --git a/languages/i18n/csb.json b/languages/i18n/csb.json index 8877f738c8..a35bc23a7a 100644 --- a/languages/i18n/csb.json +++ b/languages/i18n/csb.json @@ -8,7 +8,8 @@ "MinuteElectron", "Warszk", "לערי ריינהארט", - "아라" + "아라", + "Kirsan" ] }, "tog-underline": "Pòdsztrëchiwùjë lënczi:", @@ -18,24 +19,24 @@ "tog-extendwatchlist": "Rozwinie lëstã ùzérónëch artiklów bë wëskrzënic wszëtczé zmianë, ni le blós slédné", "tog-usenewrc": "Ùżëjé rozwinãti wëzdrzatk slédnych zjinaków (nót je JavaScript)", "tog-numberheadings": "Aùtomatné numerowanié nôgłówków", - "tog-showtoolbar": "Wëskrzrni listwã nôrzãdzów edicëji (nót je JavaScript)", - "tog-editondblclick": "Editëjë starnë przez dëbeltné klëkniãcé (nót je JavaScript)", - "tog-editsectiononrightclick": "Włączë edicëjã sekcëji bez klëkniãcé prawą knąpą mëszë
na titlu sekcëji (JavaScript)", - "tog-watchcreations": "Dodôwôj starnë, chtërné ùsôdzã, do mòji lëstë ùzérónëch artiklów", - "tog-watchdefault": "Dodôwôj starnë, chtërné editëjã do mòji lëstë ùzérónëch artiklów", - "tog-watchmoves": "Dodôwôj starnë jaczé przenoszã do mòji lëstë ùzérónëch artiklów", - "tog-watchdeletion": "Dodôwôj starnë jaczé rëmóm do mòji lëstë ùzérónëch artiklów", + "tog-showtoolbar": "Wëskrzëni listwã nôrzãdzów edicje", + "tog-editondblclick": "Editëjë starnë przez dëbeltné klëkniãcé", + "tog-editsectiononrightclick": "Włączë edicjã sekcji bez klëkniãcé prawą knąpą mëszë na titlu sekcje", + "tog-watchcreations": "Dodôwôj do mòji lëstë ùzérónëch artiklów starnë, chtërné ùsôdzã, i lopczi, chtërné wladëjã", + "tog-watchdefault": "Dodôwôj do mòji lëstë ùzérónëch artiklów starnë i lopczi, chtërné editëjã.", + "tog-watchmoves": "Dodôwôj do mòji lëstë ùzérónëch artiklów starnë i lopczi, jaczé przenoszã.", + "tog-watchdeletion": "Dodôwôj do mòji lëstë ùzérónëch artiklów starnë i lopczi, jaczé rëmóm.", "tog-minordefault": "Zaznaczë wszëtczé edicëje domëslno jakno môłé", "tog-previewontop": "Pòkażë pòdzérk przed kastką edicëji", "tog-previewonfirst": "Pòkażë pòdzérk ju przed pierszą edicëją", - "tog-enotifwatchlistpages": "Wëslë mie e-mail czedë starna jaką ùzéróm je zmieniwónô", + "tog-enotifwatchlistpages": "Wësli mie e-mail czedë je zmieniwónô starna abò lopk, jaczi ùzéróm.", "tog-enotifusertalkpages": "Wëslë mie e-mail czedë zmieniwónô je mòja starna diskùsëji", - "tog-enotifminoredits": "Wëslë mie e-mail téż dlô môłich zmianów starnów", + "tog-enotifminoredits": "Wësli mie e-mail téż dlô môłich zmianów starnów i lopków.", "tog-enotifrevealaddr": "Pòkażë mòją adresã e-mail w òdkôzëwùjącym mailu", "tog-shownumberswatching": "Pòkażë lëczba ùzérającëch brëkòwników", - "tog-oldsig": "Pòdzérk wëzdrzatkù twòjegò pòdpisënka", + "tog-oldsig": "Wëzdrzatk twòjegò pòdpisënkù:", "tog-fancysig": "Wzérôj na pòdpisënk jakno na wikikòd (bez aùtomatnych lënków)", - "tog-uselivepreview": "Brëkùjë wtimczasnegò pòdzérkù (JavaScript) (eksperimentalné)", + "tog-uselivepreview": "Brëkùjë wtimczasnegò pòdzérkù", "tog-forceeditsummary": "Pëtôj przed wéńdzenim do pùstégò pòdrechòwania edicëji", "tog-watchlisthideown": "Zatacë mòjé edicëje z lëstë ùzérónëch artiklów", "tog-watchlisthidebots": "Zatacë edicëje botów z lëstë ùzérónëch artiklów", @@ -49,7 +50,7 @@ "tog-norollbackdiff": "Pòcësni wëskrzënianié zjinaków pò copniãcô sã", "underline-always": "Wiedno", "underline-never": "Nigdë", - "underline-default": "Domëslny przezérnik", + "underline-default": "Tak jak w domëslnym przezérnikù abò skórczi.", "editfont-style": "Sztél fònta w edicjowim pòlu:", "editfont-default": "Domëslny przezérnik", "editfont-monospace": "fònt ò stałi szérzé", @@ -121,9 +122,9 @@ "newwindow": "(òtmëkô sã w nowim òczenkù)", "cancel": "Anulujë", "moredotdotdot": "Wicy...", - "mypage": "Mòja starna", - "mytalk": "Diskùsëjô", - "anontalk": "Diskùsëjô dlô ti IP-adresë", + "mypage": "Starna", + "mytalk": "Diskùsjô", + "anontalk": "Diskùsjô", "navigation": "Nawigacëjô", "and": " ë", "qbfind": "Nalézë", @@ -136,6 +137,7 @@ "actions": "Dzéjania", "namespaces": "Rum mionów:", "variants": "Wariantë", + "navigation-heading": "Nawigacyjné menu", "errorpagetitle": "Fela", "returnto": "Nazôd do starnë $1.", "tagline": "Z {{SITENAME}}", @@ -190,7 +192,7 @@ "jumptosearch": "szëkbë", "aboutsite": "Ò {{SITENAME}}", "aboutpage": "Project:Ò_{{SITENAME}}", - "copyright": "Zamkłosc hewòtny starnë je ùżëczónô wedle reglów $1.", + "copyright": "Zamkłosc hewòtny starnë je ùżëczónô wedle reglów $1, jeżlë nie pòdóno jinaczi.", "copyrightpage": "{{ns:project}}:Ùsôdzkòwé_prawa", "currentevents": "Aktualné wëdarzenia", "currentevents-url": "Project:Aktualné wëdarzenia", @@ -280,27 +282,29 @@ "createaccount": "Założë nowé kònto", "gotaccount": "Masz ju kònto? '''$1'''.", "gotaccountlink": "Wlogùjë", - "createaccountmail": "òb e-mail", + "createaccountmail": "Ùżij timczasowégò hasła i wësli je na pòdóny adres e-mail.", "badretype": "Wprowadzone parole jinaczą sã midze sobą.", "userexists": "To miono brëkòwnika je ju w ùżëcym. Proszã wëbrac jiné miono.", "loginerror": "Fela logòwaniô", - "loginsuccesstitle": "ùdałé logòwanié", + "loginsuccesstitle": "Ùdałé logòwanié", "loginsuccess": "Të jes wlogòwóny do {{SITENAME}} jakno \"$1\".", - "nosuchuser": "Nie dô brëkòwnika ò mionie \"$1\".\nSprôwdzë pisënk abò [[Special:CreateAccount|ùsôdzë nowé kònto]].", + "nosuchuser": "Nie mô brëkòwnika ò mionie \"$1\".\nW pòzwie brëkòwnika mô znaczenié wiôlgòsc lëtrów.\nSprawdzë pisënk abò [[Special:CreateAccount|ùsadzë nowé kònto]].", "nouserspecified": "Mùszisz pòdac miono brëkòwnika.", "wrongpassword": "Lëchô parola.\nSpróbùjë znowa.", "wrongpasswordempty": "Wpisónô parola je pùstô\nSpróbùjë znowa.", "passwordtooshort": "Parola mùszi zamëkac w se co nômni $1 {{PLURAL:$1|céch|céchë|céchów}}.", - "mailmypassword": "Wëslë nową parolã e-mailą", + "mailmypassword": "Zetrzéc hasło.", "passwordremindertitle": "Nowô doczasnô parola dlô {{SITENAME}}", "passwordremindertext": "Chtos (gwës Të, z adresë $1) pòprosëł ò wësłanié nowi\nparolë dlô {{SITENAME}} ($4). Aktualnô parola dlô brëkòwnika\n\"$2\" òsta ùsôdzonô ë nastôwionô jakno \"$3\". Jeżlë to bëło twòją\njintencëją, mùszisz sã terô wlogòwac ë zmienic swòją parolã.\nNowô parola je wôznô {{PLURAL:$5|dzéń|$5 dni}}.\nJeżlë chto jinszi wësłôł to zapëtanié, abò pamiãtôsz swòją parolã\në chcesz jã dali bez zmianë brëkòwac, zjignorëje to wiadło ë\nrobi dali ze starną parolą.", "noemail": "W baze ni ma email-adresë dlô brëkòwnika \"$1\".", "acct_creation_throttle_hit": "Môsz ùsôdzoné ju {{PLURAL:$1|1 kònto|$1 kontów}}.\nNi mòżesz miec ju wicy.", - "emailauthenticated": "Twòjô adresa e-mail òsta pòcwierdzonô $2 ò $3.", + "emailauthenticated": "Twój adres e-mail òstôł pòcwierdzóny $2 ò $3.", "accountcreated": "Konto założone", - "accountcreatedtext": "Konto brëkòwnika dlô $1 je założone.", + "accountcreatedtext": "Kònto brëkòwnika dlô [[{{ns:User}}:$1|$1]], [[{{ns:User talk}}:$1|talk]] òstało ùsadzóné.", "createaccount-title": "Kònto ùsôdzoné dlô {{SITENAME}}", "loginlanguagelabel": "Jãzëk: $1", + "pt-login": "Wlogùj mie", + "pt-createaccount": "Ùsadzë kònto", "changepassword": "Zmiana parolë", "oldpassword": "Stôrô parola:", "newpassword": "Nowô parola", @@ -326,28 +330,28 @@ "sig_tip": "Twój pòdpisënk z datumã a czasã", "hr_tip": "Hòrizontalnô linijô (brëkùjë szpórowno)", "summary": "Pòdrechòwanié:", - "subject": "Téma/nagłówk:", + "subject": "Téma:", "minoredit": "To je drobnô edicëjô", "watchthis": "Ùzérôj", "savearticle": "Zapiszë artikel", "preview": "Pòdzérk", "showpreview": "Wëskrzëni pòdzérk", "showdiff": "Wëskrzëni zmianë", - "anoneditwarning": "'''Bôczë:''' Të nie je wlogòwóny. Twòjô adresa IP mdze zapisónô w historëji edicëji ti starnë.", + "anoneditwarning": "Bôczë: Të nie je wlogòwóny. Jeżlë wëkònôsz jakąs zmianã, twój adres IP mdze widoczny pùbliczno. Jeżlë [$1 wlogùjesz sã] abò [$2 ùsadzësz kònto]twòje zjinaczi òstóną przëpisóné do kònta, co wicy mającë kònto òtrzimôsz rozmajité ùdogòdnienia.", "summary-preview": "Pòdzérk òpisënka:", "blockedtitle": "Brëkòwnik je zascëgóny", "blockedtext": "'''Twòje kònto abò ë IP-adresa òstałë zablokòwóné.'''\n\nZablokòwôł je $1.\nPòdónô przëczëna to:''$2''.\n\n * Zôczątk blokadë: $8\n * Kùńc blokadë: $6\n * Cél blokadë: $7\n\n\nBë zgwësnic sprawã zablokòwaniô mòżesz skòntaktowac sã z $1 abò jińszim [[{{MediaWiki:Grouppage-sysop}}|administratorã]].\nBoczë, że të ni mòżesz stądka sélac e-mailów, jeżlë nié môsz jesz zaregisterowóné e-mailowé adresë w [[Special:Preferences|nastôwach]].\nTwòjô aktualnô adresa IP to $3, a zablokòwónô adresa ID to #$5.\nProszëmë pòdac wëższé pòdôłczi przë wszëtczich pëtaniach.", "loginreqlink": "Wlogùjë", "loginreqpagetext": "$1 sã, żebë przezérac jinszé starnë.", "accmailtitle": "Parola wësłónô.", - "accmailtext": "Przëtrôfkòwò wëgenerowónô parola dlô [[User talk:$1|$1]] òsta wësłónô do $2.\n\nParolã dlô negò nowégò kònta mòże zmienic pò wlogòwaniu na starnie ''[[Special:ChangePassword|zjinaka parolë]]''.", + "accmailtext": "Przëtrôfkòwò wëgenerowónô parola dlô [[User talk:$1|$1]] òsta wësłónô do $2. Parolã dlô negò nowégò kònta mòże zmienic pò wlogòwaniu na starnie [[Special:ChangePassword|zjinaka parolë]] .", "newarticle": "(Nowi)", "newarticletext": "Môsz przëszłi z lënkù do starnë jaka jesz nie òbstoji.\nBë ùsôdzëc artikel, naczni pisac w kastce niżi (òb. [$1 starnã pòmòcë]\ndlô wicy wëdowiédzë).\nJeżlë jes të tuwò bez zmiłkã, le klëkni w swòjim przezérnikù knąpã '''nazôd'''.", - "anontalkpagetext": "----''To je starna dyskùsëji anonimòwiégò brëkòwnika, chtëren nie ùsôdzëł jesz swòjegò kòntae, abò gò nie brëkùje.\nAbë gò rozpòznac, ùżëwómë adresów IP.\nTakô adresa IP, mòże bëc równak brëkòwónô przez wiele lëdzy.\nJeżlë jes anonimòwim brëkòwnikã ë ùwôżôsz, że ne wiadła nie są do ce sczerowóne, tedë [[Special:CreateAccount|ùsôdzë nowé kònto]] abò [[Special:UserLogin|wlogùjë sã]], bë niechac niezrozmeiniô z jinyma anonimòwima brëkòwnikama.''", - "noarticletext": "Felëje starna ò tim titlu.\nMòżesz [[Special:Search/{{PAGENAME}}|szëkac za {{PAGENAME}} na jinych starnach]],\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} szëkac w logù] abò [{{fullurl:{{FULLPAGENAME}}|action=edit}} ùsôdzëc nã starnã]", + "anontalkpagetext": "----\nTo je starna diskùsje anonimòwégò brëkòwnika, chtëren nie ùsadzëł jesz swòjegò kònta, abò gò nie brëkùje.\nAbë gò rozpòznac, ùżëwómë adresów IP.\nTakô adresa IP mòże bëc równak brëkòwónô przez wiele lëdzy.\nJeżlë jes anonimòwim brëkòwnikã i ùwôżôsz, że ne wiadła nie są do ce sczerowóné, tedë [[Special:CreateAccount|ùsadzë nowé kònto]] abò [[Special:UserLogin|wlogùj sã]], bë niechac niezrozmieniô z jinyma anonimòwima brëkòwnikama.''", + "noarticletext": "Felëje starna ò tim titlu.\nMòżesz [[Special:Search/{{PAGENAME}}|szëkac za {{PAGENAME}} na jinych starnach]],\n[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} szëkac w logù] abò [{{fullurl:{{FULLPAGENAME}}|action=edit}} ùsadzëc nã starnã]", "clearyourcache": "'''Bôczë: Pò zapisanim, mòże bãdzesz mùszôł òminąc pamiãc przezérnika bë òbaczëc zmianë.'''\n'''Mozilla / Firefox / Safari:''' przëtrzëmôj ''Shift'' òbczas klëkaniô na ''Zladëjë znowa'', abò wcësni ''Ctrl-F5'' abò ''Ctrl-R'' (''Command-R'' na kòmpùtrach Mac);\n'''Konqueror:''': klëkni na knąpã ''Zladëjë znowa'', abò wcësni ''F5'';\n'''Opera:''' wëczëszczë pòdrãczną pamiãc w ''Tools→Preferences'';\n'''Internet Explorer:'''przëtrzëmôj ''Ctrl'' òbczas klëkaniô na ''Zladëjë znowa'', abò wcësni ''Ctrl-F5''.", "updated": "(Zaktualnioné)", - "previewnote": "'''To je blós pòdzérk - artikel jesz nie je zapisóny!'''", + "previewnote": "To je blós pòdzérk.\n Artikel jesz nie je zapisóny!", "editing": "Edicëjô $1", "editingsection": "Edicëjô $1 (dzél)", "explainconflict": "Chtos sfórtowôł wprowadzëc swòją wersëjã artikla òbczôs Twòji edicëji.\nGórné pòle edicëji zamëkô w se tekst starnë aktualno zapisóny w pòdôwkòwi baze.\nTwòje zmianë są w dólnym pòlu edicëji.\nBë wprowadzëc swòje zmianë mùszisz zmòdifikòwac tekst z górnégò pòla.\n'''Blós''' tekst z górnégò pòla mdze zapisóny w baze czej wcësniesz \"{{int:savearticle}}\".", @@ -375,21 +379,21 @@ "page_last": "kùńc", "histlegend": "Legenda: (aktualnô) = różnice w przërównanim do aktualny wersëje,\n(wczasniészô) = różnice w przërównanim do wczasniészi wersëje, D = drobné edicëje", "history-fieldset-title": "Przezérôj historëjã", - "histfirst": "Stôrszé", - "histlast": "Nowszé", + "histfirst": "òd nôstarszich", + "histlast": "òd nônowszich", "history-feed-item-nocomment": "$1 ò $2", "rev-delundel": "pòkażë/zatacë", "rev-showdeleted": "pokôż", "revdelete-show-file-submit": "Jo", - "revdelete-radio-set": "Jo", - "revdelete-radio-unset": "Nié", + "revdelete-radio-set": "ùtacony", + "revdelete-radio-unset": "widzawny", "revdel-restore": "Zjinaczë widzawnotã", "pagehist": "Historëjô starnë", "deletedhist": "Rëmniãtô historëjô edicëji", "revdelete-hide-current": "Pòkôza sã fela przë taceniu wersëji datowóny na $2, $1. To je nônowszô wersëjô starnë, chtërnô ni mòże bëc zataconô.", "revdelete-show-no-access": "Pòkôza sã fela przë próbie wëskrzënieniô elementu datowónegò na $2, $1. Widzawnota negò elementu òsta ògrańczonô - ni môsz przëstãpù.", "revertmerge": "Rozdzélë", - "history-title": "Historëjô wersëji dlô \"$1\"", + "history-title": "Historiô zjinaków dlô \"$1\"", "lineno": "Lëniô $1:", "compareselectedversions": "Przërównôj wëbróné wersëje", "editundo": "doprowadzë nazôd", @@ -401,17 +405,17 @@ "viewprevnext": "Òbaczë ($1 {{int:pipe-separator}} $2) ($3).", "searchprofile-advanced": "Awansowóné", "search-result-size": "$1 ({{PLURAL:$2|1 słowò|$2 słowa|$2 słów}})", - "search-redirect": "(przeczérowanié $1)", + "search-redirect": "(przeczérowanié z $1)", "search-section": "(dzél $1)", "search-suggest": "Të mëszlôł ò: $1", "search-interwiki-caption": "Sosterné ùdbë", - "search-interwiki-default": "Skùtczi dlô $1:", + "search-interwiki-default": "Wëniczi òd $1:", "search-interwiki-more": "(wicy)", "searchall": "wszëtczé", "powersearch-legend": "Awansowónô szëkba", "powersearch-ns": "Szëkba w rumach mionów:", "preferences": "Preferencëje", - "mypreferences": "Mòje nastôwë", + "mypreferences": "Nastôwë", "prefs-edits": "Lëczba edicëjów:", "prefs-skin": "Wëzdrzatk", "skin-preview": "Pòdzérk", @@ -424,8 +428,6 @@ "prefs-misc": "Jine", "saveprefs": "Zapiszë", "prefs-editing": "Edicëjô", - "rows": "Régów:", - "columns": "Kòlumnów:", "searchresultshead": "Szëkba", "stub-threshold": "Greńca dlô fòrmatowaniô lënków stubów:", "recentchangesdays": "Kùli dni pòkazëwac w slédnëch edicëjach:", @@ -433,7 +435,7 @@ "savedprefs": "Twòjé nastôwë òstałë zapisóné.", "timezonelegend": "Czasowô cona:", "localtime": "Môlowi czas:", - "timezoneuseserverdefault": "Ùżëjë domëslnégò czasu serwera", + "timezoneuseserverdefault": "Ùżij domëslny dlô ti wiki ($1)", "timezoneuseoffset": "Jinô (specyfikùjë różnicã)", "servertime": "Czas serwera:", "guesstimezone": "Wezmi z przezérnika", @@ -448,7 +450,7 @@ "timezoneregion-indian": "Indijsczi Òcean", "timezoneregion-pacific": "Spòkójny Òcean", "allowemail": "Włączë mòżlewòtã sélaniô e-mailów òd jinëch brëkòwników", - "prefs-searchoptions": "Òptacëje szëkbë", + "prefs-searchoptions": "Szëkba", "prefs-namespaces": "Rum mionów", "default": "domëszlné", "prefs-files": "Lopczi", @@ -458,19 +460,19 @@ "prefs-reset-intro": "Na ti starnie mòże doprowôdzëc nazôd domëslné nastôwë dlô ti starnë.\nNegò dzéjaniô ni mòżé pòzdze ju copnąc.", "prefs-emailconfirm-label": "Pòcwierdzenié e-mailowi adresë:", "youremail": "E-mail:", - "username": "Miono brëkòwnika:", - "prefs-memberingroups": "Nôlëżnik {{PLURAL:$1|karna|karnów}}", + "username": "{{GENDER:$1|Miono brëkòwnika}}:", + "prefs-memberingroups": "{{GENDER:$2| Nôlëżnik}}{{PLURAL:$1|karna|karnów}}", "prefs-registration": "Czas registracëji:", "yourrealname": "Miono ë nôzwëskò:", "yourlanguage": "Jãzëk:", - "yourvariant": "Wariant:", + "yourvariant": "Wariant jãzëka zamkłoscë:", "yournick": "Pòdpisënk:", "badsig": "Òchëbny pòdpisënk, sprôwdzë tadżi HTML.", "badsiglength": "Pòdpisënk je za dłudżi.\nMô bëc mni jakno $1 {{PLURAL:$1|znak|znaczi/znaków}}.", "gender-male": "Chłop", "gender-female": "Białka", "email": "E-mail", - "prefs-help-realname": "Prôwdzewi miono je òptacjowé a czej je dôsz, òstanié ùżëté do pòdpisaniô Twòjégò wkłôdu", + "prefs-help-realname": "Prôwdzëwé miono je òptacjowé, a czej je dôsz, òstanié ùżëté do pòdpisaniô Twòjégò wkładu", "prefs-help-email": "Adresa e-mail je òptacëjnô, zezwôlô równak sélac do ce nową parolã jak tã zabëjesz.\nMòżesz zezwòlëc jinszim brëkòwniką na łączbã z Tobą przez Twòją starnã abò starnã diskùsëji, bez mùszebnotë wëskrzënianiô swòjich pòdôwków.", "editinguser": "Zmiana praw brëkòwnika '''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]])", "group": "Karno:", @@ -525,7 +527,7 @@ "rclistfrom": "Pòkażë nowé zmianë òd $3 $2", "rcshowhideminor": "$1 môłé zmianë", "rcshowhidebots": "$1 botë", - "rcshowhideliu": "$1 zalogòwónëch brëkòwników", + "rcshowhideliu": "$1 zaregistrowónëch brëkòwników", "rcshowhideanons": "$1 anonymòwëch brëkòwników", "rcshowhidepatr": "$1 òbzérónë edicëje", "rcshowhidemine": "$1 mòjé edicëje", @@ -574,7 +576,7 @@ "filehist-dimensions": "Miara", "filehist-filesize": "Miara lopka", "filehist-comment": "Òpisënk", - "imagelinks": "Lënczi lopka", + "imagelinks": "Wëkòrzëstanie lopka", "linkstoimage": "{{PLURAL:$1|Hewò je starna jakô òdwòłëje|Hewò są starnë jaczé òdwòłëją}} sã do negò lopka:", "nolinkstoimage": "Niżódnô starna nie òdwòłëje sã do negò lopka.", "sharedupload": "Nen lopk je na $1 ë mòże bëc brëkòwóny w jinych ùdbach.", @@ -704,9 +706,9 @@ "namespace": "Rum mionów:", "invert": "Òdwrócë zaznaczenié", "blanknamespace": "(Przédnô)", - "contributions": "Wkłôd brëkòwników", + "contributions": "Wkłôd {{GENDER:$1|brëkòwnika|brëkòwniczczi}}", "contributions-title": "Wkłôd brëkòwnika $1", - "mycontris": "Mòje edicëje", + "mycontris": "Mój wkłôd", "contribsub2": "Dlô brëkòwnika $1 ($2)", "uctop": "(slédnô)", "month": "Òd miesąca (ë wczasni):", @@ -725,11 +727,11 @@ "nolinkshere": "Niżódnô starna nie lënkùje do '''[[:$1]]'''.", "isredirect": "starna przeczerowaniô", "istemplate": "doparłãczony", - "isimage": "lënk òbrôzka", + "isimage": "lënk do lopka", "whatlinkshere-prev": "{{PLURAL:$1|wczasniészé|wczasniészé $1}}", "whatlinkshere-next": "{{PLURAL:$1|nôslédné|nôslédné $1}}", "whatlinkshere-links": "← lëkùjącé", - "whatlinkshere-hideredirs": "$1 przeczérownia", + "whatlinkshere-hideredirs": "$1 przeczérowania", "whatlinkshere-hidetrans": "$1 doparłãczenia", "whatlinkshere-hidelinks": "$1 lënczi", "whatlinkshere-filters": "Filtrë", @@ -776,15 +778,16 @@ "allmessagesnotsupportedDB": "'''{{ns:special}}:Allmessages''' nie mòże bëc brëkòwónô, temù że '''$wgUseDatabaseMessages''' je wëłączony.", "thumbnail-more": "Zwiszi", "import": "Impòrtëjë starnë", - "tooltip-pt-userpage": "Twòja starna brëkòwnika", - "tooltip-pt-mytalk": "Twòjô starna diskùsëji", - "tooltip-pt-preferences": "Mòje nastôwë", + "tooltip-pt-userpage": "{{GENDER:|Twòja}} starna brëkòwnika", + "tooltip-pt-mytalk": "{{GENDER:|Twòja}} starna diskùsje", + "tooltip-pt-preferences": "{{GENDER:|Mòje}}nastôwë", "tooltip-pt-watchlist": "Lësta artiklów jaczé òbzérôsz za zmianama", - "tooltip-pt-mycontris": "Lësta twòjich edicëjów", + "tooltip-pt-mycontris": "Lësta {{GENDER:|twòjich}} edicji", "tooltip-pt-login": "Rôczimë do wlogòwaniô sã, nie je to równak mùszebné.", "tooltip-pt-logout": "Wëlogòwanié", + "tooltip-pt-createaccount": "Zachãcëwómë do ùsadzeniô kònta i wlogòwaniô, chòc nie je to òbrzészk.", "tooltip-ca-talk": "Diskùsëjô zamkłoscë ti starnë", - "tooltip-ca-edit": "Mòżesz editowac nã starnã.\nProszã brëkòwac knąpë pòdzérkù przed zapisaniém.", + "tooltip-ca-edit": "Edituj nã starnã.", "tooltip-ca-addsection": "Zrëszë nowi dzél", "tooltip-ca-viewsource": "Na starna je zazychrowónô.\nMòżesz òbaczëc ji zdrój.", "tooltip-ca-history": "Stôrszé wersëje ti starnë", @@ -796,6 +799,7 @@ "tooltip-search": "Szëkba {{SITENAME}}", "tooltip-search-go": "Biéj do starnë z akùratno taczim mionã, jeżlë takô je", "tooltip-search-fulltext": "Szëkba za wpisónym tesktã na starnach", + "tooltip-p-logo": "Òbaczë przédną starnã", "tooltip-n-mainpage": "Òbôczë przédną starnã", "tooltip-n-mainpage-description": "Biéj do przédny starnë", "tooltip-n-portal": "Ò ti ùdbie, co mòżesz zrobic, co a gdze mòżesz nalezc.", @@ -807,7 +811,7 @@ "tooltip-t-recentchangeslinked": "Slédné zjinaczi na starnach, do chtërnëch na starna lënkùje", "tooltip-feed-rss": "Pòwrózk RSS dlô ti starnë", "tooltip-feed-atom": "Pòwrôzk Atom dlô ti starnë", - "tooltip-t-contributions": "Wëskrzëni lëstã edicëji negò brëkòwnika", + "tooltip-t-contributions": "Wëskrzëni lëstã edicji {{GENDER:$1|negò brëkòwnika|ti brëkòwniczczi}}", "tooltip-t-emailuser": "Wëslë e-mail do tegò brëkòwnika", "tooltip-t-upload": "Wladëjë lopczi", "tooltip-t-specialpages": "Lësta specjalnëch starnów", @@ -815,7 +819,7 @@ "tooltip-t-permalink": "Prosti lënk do ti wersëji starnë", "tooltip-ca-nstab-main": "Wëskrzëni starnã zamkłoscë", "tooltip-ca-nstab-user": "Wëskrzëni starnã brëkòwnika", - "tooltip-ca-nstab-special": "To je specjlanô starna, chtërny ni mòżesz editowac", + "tooltip-ca-nstab-special": "To je specjalnô starna, chtërny ni mòżesz editowac", "tooltip-ca-nstab-project": "Òbôczë starnã ùdbë", "tooltip-ca-nstab-image": "Wëskrzëni starnã lopka", "tooltip-ca-nstab-template": "Wëskrzëni szablónã", @@ -838,6 +842,7 @@ "othercontribs": "Òpiarté na prôcë $1.", "others": "jiné", "spamprotectiontitle": "Anti-spamòwi filter", + "pageinfo-toolboxlink": "Jinfòrmacje ò ti starnie.", "previousdiff": "← Pòprzédnô edicëjô", "nextdiff": "Nôslédnô edicëjô →", "imagemaxsize": "Ògrańczë na starnie òpisënkù òbrôzków jich miarã do:", @@ -845,7 +850,7 @@ "file-info-size": "$1 × $2 pikslów, miara lopka: $3, ôrt MIME: $4", "file-nohires": "Felëje wikszô miara.", "svg-long-desc": "Lopk SVG, nominalno $1 × $2 pikslów, miara lopka: $3", - "show-big-image": "Fùl miara", + "show-big-image": "Pierwòszny lopk", "newimages": "Galerëjô nowich lopków", "ilsubmit": "Szëkôj", "bydate": "wedle datumù", @@ -854,7 +859,7 @@ "metadata-help": "Nen lopk zamëkô w se dodôwną wëdowiédzã, prôwdopòdobno dodóné przez cyfrową kamerã abò skaner ùżëti do ùsôdzeniô abò digitalizacëji.\nJeżlë lopk bëł mòdifikòwóny, pòdôwczi mògą bëc w dzéłu nierówné z paramétrama przerôbionegò lopka.", "metadata-expand": "Wëskrzëni detale", "metadata-collapse": "Zatacë detale", - "metadata-fields": "Wëskrzënioné niżi pòla EXIF bãdą widzawné na starnie graficzi.\nJinszé pòla bãdą domëslno zataconé.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude", + "metadata-fields": "Wëskrzënioné niżi pòla metadanëch bãdą widzawné na starnie graficzi.\nJinszé pòla bãdą domëslno zataconé.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude", "exif-source": "Zdrój", "exif-languagecode": "Jãzëk", "exif-iimcategory-spo": "Szpòrt", diff --git a/languages/i18n/egl.json b/languages/i18n/egl.json index 1d12d07fcc..e1efa5a049 100644 --- a/languages/i18n/egl.json +++ b/languages/i18n/egl.json @@ -14,6 +14,7 @@ "tog-hideminor": "Lōga 'l mudéfichi pió céchi int al j ûltmi mudéfichi.", "tog-hidepatrolled": "Lōga 'l mudéfichi verifichêdi int al j ûltmi mudéfichi", "tog-newpageshidepatrolled": "Lōga al pàgini verifichêdi da l'elèinch dal pàgini pió nōvi.", + "tog-hidecategorization": "Scònd al categoréi dal pàgini", "tog-extendwatchlist": "Fà vèder tót' al mudéfichi fât a i tgnû sòt ôc, mìa sōl l'ûltma.", "tog-usenewrc": "Unés al mudéfichi per pàgina int al j ûltmi mudéfichi e in quî tgnû sòt' ôc.", "tog-numberheadings": "Cûnta automâtica di tétol ed sesiòun.", @@ -24,6 +25,7 @@ "tog-watchdefault": "Zûnta al pàgini e i file mudifichê int i tgnû 'd ôc specêl.", "tog-watchmoves": "Zûnta al pàgini e i file spustê int i tgnû 'd ôc specêl.", "tog-watchdeletion": "Zûnta al pàgini e i file scanşlê int i tgnû 'd ôc specêl.", + "tog-watchuploads": "Zûnta i file nōv che câregh a quî che tègn adrē", "tog-watchrollback": "Zûta al pàgini in dóv' ó fât al ritōren a la pàgina 'd préma a i tgnû 'd ôc specêl", "tog-minordefault": "Sègna ògni mudéfica cme céca (sōl cme pre-stabilî)", "tog-previewontop": "Fà vèder còl ch' ò fât sōver la caşèla ed mudéfica e mìa sòta.", @@ -498,8 +500,6 @@ "passwordreset-emaildisabled": "In cla wiki ché è stê bluchê al funsiòun ed la pôsta eletrônica.", "passwordreset-username": "Nòm utèint:", "passwordreset-domain": "Proprietê:", - "passwordreset-capture": "Vōt vèder còl che dèinter int al mesâg ed pôsta eletrônica?", - "passwordreset-capture-help": "S' es sernés cla caşèla ché, l'indirés ed pôsta eletrônica (cun la cêva 'd ingrès pruvişôria), év vîn fâ vèder, d'ed là 'd èser spidî a l'utèint.", "passwordreset-email": "Indirés pôsta eletrônica", "passwordreset-emailtitle": "Particulêr ed l'utèint só {{SITENAME}}", "passwordreset-emailtext-ip": "Quelchidûn (prubabilmèint té, cun l'indirés IP $1) l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:\n \n$2 \n\n{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. \n\nSe t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia.", @@ -891,8 +891,6 @@ "saveprefs": "Sêlva", "restoreprefs": "Turnêr a mèter al j impustasiòun ed partèinsa (in tót al sesiòun)", "prefs-editing": "Caşèla 'd mudéfica", - "rows": "Rîghi", - "columns": "Clòuni:", "searchresultshead": "Sērca", "stub-threshold": "Pôrta per i colegamèint a j abòs ($1):", "stub-threshold-disabled": "Bluchê", @@ -970,9 +968,9 @@ "prefswarning-warning": "T'é fât dal mudéfichi al tō preferèinsi ch'în mìa stêdi salvêdi. S'ét vê fōra da cla pàgina ché sèinsa clichêr \"$1\" al preferèinsi a gnîran mìa arnuvêdi.", "prefs-tabs-navigation-hint": "Sugerimèint: è pusébil druvêr i tâst frècia a mansèina e a dréta per spustêres tr'al schēdi int l'elèinch dal schēdi.", "userrights": "Gestiòun di permès relatîv a j utèint", - "userrights-lookup-user": "Gestiòun di gróp utèint", + "userrights-lookup-user": "Sernîr 'n utèint", "userrights-user-editname": "Mèt dèinter al nòm utèint:", - "editusergroup": "Mudéfica i gróp {{GENDER:$1|utèint}}", + "editusergroup": "Mudéfica i gróp utèint.", "editinguser": "Mudéfica i dirét utèint ed j {{GENDER:$1|utèint}}[[User:$1|$1]] $2", "userrights-editusergroup": "Mudéfica gróp utèint", "saveusergroups": "Sêlva i gróp{{GENDER:$1|utèint}}", @@ -982,19 +980,16 @@ "userrights-reason": "Mutîv:", "userrights-no-interwiki": "An es gh'à mìa i permès necesâri per cambiêr i dirét ed j utèint in sém a êter sît.", "userrights-nodatabase": "Al databēş $1 al gh'é mìa o an n' mìa un databêş lochêl.", - "userrights-nologin": "Per dêr i dirét a j utèint l'é necesâri [[Special:UserLogin|fêr l'ingrès]] cme aministardōr.", - "userrights-notallowed": "An 't gh'ê mìa al permès per zuntêr o tōr via i permès utèint.", "userrights-changeable-col": "Gróp ch'es pōlen mudifichêr.", "userrights-unchangeable-col": "Gróp ch'an 's pōlen mìa mudifichêr.", "userrights-conflict": "Cuntrâst ed mudéfica di dirét utèint! Cuntròla e cunfērma al tó mudéfichi.", - "userrights-removed-self": "T'é tôt via i tō dirét. E dòunca, an 't prê pió andêr dèinter a cla pàgina ché.", "group": "Gróp:", "group-user": "Utèint", "group-autoconfirmed": "Utèint cunvalidê da per ló", "group-bot": "Bot", "group-sysop": "Aministradōr", "group-bureaucrat": "Funsionâri", - "group-suppress": "Oversight", + "group-suppress": "Soppressori", "group-all": "(tót)", "group-user-member": "{{GENDER:$1|utèint}}", "group-autoconfirmed-member": "{{GENDER:$1|utèint convalidê da per ló}}", @@ -1077,7 +1072,6 @@ "right-siteadmin": "Blōca e şblōca al databêş", "right-override-export-depth": "Pôrta fōra al pàgini cun insèm al pàgini coleghêdi per 'na larghèsa ed 5", "right-sendemail": "Spidés pôsta eletrônica a êter utèint", - "right-passwordreset": "A vèd i mesâg 'd arnōv ed la cêva 'ed ingrès", "right-managechangetags": "Fa e mèt in funsiòun/blôca al j [[Special:Tags|etichèti]]", "right-applychangetags": "Tâca dal [[Special:Tags|tichèti]] al tō mudéfichi", "right-changetags": "Zûta e tó via [[Special:Tags|tichèti]] precîşi só versiòun ónichi o vōş ed regéster", @@ -1103,11 +1097,11 @@ "action-upload_by_url": "carghêr cól file ché da 'n indirés URL", "action-writeapi": "drōva al j API in scritûra", "action-delete": "scanşlêr cla pàgina ché", - "action-deleterevision": "scanşlêr cla versiòun ché", - "action-deletedhistory": "guêrda la stòria scanşlêda de sté pàgina", + "action-deleterevision": "scanşlêr al versiòun", + "action-deletedhistory": "guêrda la stòria scanşlêda ed 'na pàgina", "action-browsearchive": "serchêr pàgini scanşlêdi", - "action-undelete": "tōr indrê cla pàgina ché", - "action-suppressrevision": "turnêr a vèder e mèter al mudéfichi lughêdi", + "action-undelete": "tōr indrê pàgini", + "action-suppressrevision": "turnêr a vèder e turnêr a mèter al versiòun lughêdi", "action-suppressionlog": "guardêr sté regéster privê", "action-block": "bluchê sté utèint in scritûra", "action-protect": "cambiêr i livē 'd prutesiòun per cla pàgina ché", @@ -1590,5 +1584,5 @@ "feedback-cancel": "Scanşela", "feedback-message": "Mesâg", "feedback-subject": "Argomèint:", - "searchsuggest-search": "Sèirca" + "searchsuggest-search": "Sērca dèinter ed {{SITENAME}}" } diff --git a/languages/i18n/en-gb.json b/languages/i18n/en-gb.json index 9991eb75d4..8957b4c992 100644 --- a/languages/i18n/en-gb.json +++ b/languages/i18n/en-gb.json @@ -26,7 +26,8 @@ "Paladox", "SamanthaNguyen", "Usandaru555", - "Aefgh39622" + "Aefgh39622", + "Anomie" ] }, "tog-underline": "Link underlining:", @@ -56,7 +57,7 @@ "tog-shownumberswatching": "Show the number of watching users", "tog-oldsig": "Your existing signature:", "tog-fancysig": "Treat signature as wikitext (without an automatic link)", - "tog-uselivepreview": "ක්‍රියාත්මකව අති පෙරහුරුවක් පෙන්වන්න", + "tog-uselivepreview": "Use live preview", "tog-forceeditsummary": "Prompt me when entering a blank edit summary", "tog-watchlisthideown": "Hide my edits from the watchlist", "tog-watchlisthidebots": "Hide bot edits from the watchlist", @@ -208,9 +209,9 @@ "undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}", "viewdeleted_short": "View {{PLURAL:$1|one deleted edit|$1 deleted edits}}", "protect": "Protect", - "protect_change": "ترميميو", + "protect_change": "change", "protectthispage": "Protect this page", - "unprotect": "تحفظ جي سطح بدلايو", + "unprotect": "Change protection", "unprotectthispage": "Change protection of this page", "newpage": "New page", "talkpage": "Discuss this page", @@ -229,7 +230,7 @@ "viewhelppage": "View help page", "categorypage": "View category page", "viewtalkpage": "View discussion", - "otherlanguages": "Muilla kielillä", + "otherlanguages": "In other languages", "redirectedfrom": "(Redirected from $1)", "redirectpagesub": "Redirect page", "redirectto": "Redirect to:", diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 2db5f4c6fa..c771447c36 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -1148,13 +1148,14 @@ "userrights-groupsmember": "Member of:", "userrights-groupsmember-auto": "Implicit member of:", "userrights-groupsmember-type": "$1", - "userrights-groups-help": "You may alter the groups this user is in:\n* A checked box means the user is in that group.\n* An unchecked box means the user is not in that group.\n* A * indicates that you cannot remove the group once you have added it, or vice versa.", + "userrights-groups-help": "You may alter the groups this user is in:\n* A checked box means the user is in that group.\n* An unchecked box means the user is not in that group.\n* A * indicates that you cannot remove the group once you have added it, or vice versa.\n* A # indicates that you can only put back the expiration time of this group; you cannot bring it forward.", "userrights-reason": "Reason:", "userrights-no-interwiki": "You do not have permission to edit user rights on other wikis.", "userrights-nodatabase": "Database $1 does not exist or is not local.", "userrights-changeable-col": "Groups you can change", "userrights-unchangeable-col": "Groups you cannot change", "userrights-irreversible-marker": "$1*", + "userrights-no-shorten-expiry-marker": "$1#", "userrights-expiry-current": "Expires $1", "userrights-expiry-none": "Does not expire", "userrights-expiry": "Expires:", @@ -1163,6 +1164,7 @@ "userrights-expiry-options": "1 day:1 day,1 week:1 week,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year", "userrights-invalid-expiry": "The expiry time for group \"$1\" is invalid.", "userrights-expiry-in-past": "The expiry time for group \"$1\" is in the past.", + "userrights-cannot-shorten-expiry": "You cannot bring forward the expiry of group \"$1\". Only users with permission to add and remove this group can bring forward expiry times.", "userrights-conflict": "Conflict of user rights changes! Please review and confirm your changes.", "group": "Group:", "group-user": "Users", @@ -1553,7 +1555,7 @@ "uploaded-setting-handler-svg": "SVG that sets the \"handler\" attribute with remote/data/script is blocked. Found $1=\"$2\" in the uploaded SVG file.", "uploaded-remote-url-svg": "SVG that sets any style attribute with remote URL is blocked. Found $1=\"$2\" in the uploaded SVG file.", "uploaded-image-filter-svg": "Found image filter with URL: <$1 $2=\"$3\"> in the uploaded SVG file.", - "uploadscriptednamespace": "This SVG file contains an illegal namespace \"$1\".", + "uploadscriptednamespace": "This SVG file contains an illegal namespace \"$1\".", "uploadinvalidxml": "The XML in the uploaded file could not be parsed.", "uploadvirus": "The file contains a virus!\nDetails: $1", "uploadjava": "The file is a ZIP file that contains a Java .class file.\nUploading Java files is not allowed because they can cause security restrictions to be bypassed.", @@ -4138,6 +4140,7 @@ "mw-widgets-titleinput-description-new-page": "page does not exist yet", "mw-widgets-titleinput-description-redirect": "redirect to $1", "mw-widgets-categoryselector-add-category-placeholder": "Add a category...", + "mw-widgets-usersmultiselect-placeholder": "Add more...", "sessionmanager-tie": "Cannot combine multiple request authentication types: $1.", "sessionprovider-generic": "$1 sessions", "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-based sessions", diff --git a/languages/i18n/es.json b/languages/i18n/es.json index b45923ea2b..03ac0b5afc 100644 --- a/languages/i18n/es.json +++ b/languages/i18n/es.json @@ -3493,7 +3493,7 @@ "tags-deactivate": "desactivar", "tags-hitcount": "$1 {{PLURAL:$1|cambio|cambios}}", "tags-manage-no-permission": "No tienes permiso para gestionar las etiquetas de cambios.", - "tags-manage-blocked": "No puedes gestionar etiquetas de cambio mientras estés {{GÉNERO:$1|bloqueado|bloqueada}}.", + "tags-manage-blocked": "No puedes gestionar etiquetas de cambio mientras estés {{GENDER:$1|bloqueado|bloqueada}}.", "tags-create-heading": "Crear una etiqueta", "tags-create-explanation": "De manera predeterminada, las etiquetas nuevas estarán disponibles para su uso por usuarios y bots.", "tags-create-tag-name": "Nombre de la etiqueta:", diff --git a/languages/i18n/fr.json b/languages/i18n/fr.json index 03447f782d..cb8f742792 100644 --- a/languages/i18n/fr.json +++ b/languages/i18n/fr.json @@ -942,7 +942,7 @@ "last": "diff", "page_first": "première", "page_last": "dernière", - "histlegend": "Diff de sélection : cochez les boîtes radio des versions à comparer et appuyez sur entrée ou sur le bouton en bas.
\nLégende: ({{int:cur}}) = différence avec la dernière version, ({{int:last}}) = différence avec la précédente version, {{int:minoreditletter}} = modification mineure.", + "histlegend": "Sélection du diff : cochez les boutons radio des versions à comparer et appuyez sur entrée ou sur le bouton en bas.
\nLégende : ({{int:cur}}) = différence avec la dernière version, ({{int:last}}) = différence avec la version précédente, {{int:minoreditletter}} = modification mineure.", "history-fieldset-title": "Naviguer dans l’historique", "history-show-deleted": "Supprimés seulement", "histfirst": "les plus anciennes", diff --git a/languages/i18n/gl.json b/languages/i18n/gl.json index 5f765d5748..489f99ab08 100644 --- a/languages/i18n/gl.json +++ b/languages/i18n/gl.json @@ -23,7 +23,8 @@ "Macofe", "Banjo", "Josep Maria Roca Peña", - "Luan" + "Luan", + "Hamilton Abreu" ] }, "tog-underline": "Subliñar as ligazóns:", @@ -1107,10 +1108,14 @@ "userrights-nodatabase": "A base de datos \"$1\" non existe ou non é local.", "userrights-changeable-col": "Os grupos que pode cambiar", "userrights-unchangeable-col": "Os grupos que non pode cambiar", - "userrights-expiry-current": "Caduca 1$", + "userrights-expiry-current": "Caduca o $1", "userrights-expiry-none": "Non caduca", "userrights-expiry": "Caduca:", + "userrights-expiry-existing": "Período de caducidade actual: $2 ás $3", + "userrights-expiry-othertime": "Outro tempoː", "userrights-expiry-options": "1 día:1 día,1 semana:1 semana,1 mes:1 mes,3 meses:3 meses,6 meses:6 meses,1 ano:1 ano", + "userrights-invalid-expiry": "O tempo de caducidade para o grupo \"$1\" non é válido.", + "userrights-expiry-in-past": "O tempo de caducidade para o grupo \"$1\" está no pasado.", "userrights-conflict": "Hai un conflito na modificación dos dereitos de usuario! Por favor, revíseo e confirme os seus cambios.", "group": "Grupo:", "group-user": "Usuarios", @@ -1312,29 +1317,38 @@ "recentchanges-legend-plusminus": "(''±123'')", "recentchanges-submit": "Mostrar", "rcfilters-activefilters": "Filtros activos", + "rcfilters-restore-default-filters": "Restaurar os filtros por defecto", + "rcfilters-clear-all-filters": "Borrar todos os filtros", "rcfilters-search-placeholder": "Filtrar os cambios recentes (ollar ou comezar a escribir)", "rcfilters-invalid-filter": "Filtro no válido", + "rcfilters-empty-filter": "Non hai filtros activos. Móstranse tódalas contribucións.", "rcfilters-filterlist-title": "Filtros", "rcfilters-filterlist-noresults": "Non se atoparon filtros", "rcfilters-filtergroup-registration": "Rexistro de usuario", "rcfilters-filter-registered-label": "Rexistrado", + "rcfilters-filter-registered-description": "Editores autenticados.", "rcfilters-filter-unregistered-label": "Non rexistrado", + "rcfilters-filter-unregistered-description": "Editores que non están autenticados.", "rcfilters-filtergroup-authorship": "Editar autoría", "rcfilters-filter-editsbyself-label": "As súas propias edicións", "rcfilters-filter-editsbyself-description": "Edicións súas.", "rcfilters-filter-editsbyother-label": "Edicións doutros.", - "rcfilters-filter-editsbyother-description": "Edicións creadas por outros usuarios.", + "rcfilters-filter-editsbyother-description": "Edicións creadas por outros usuarios (non por vostede).", "rcfilters-filtergroup-userExpLevel": "Nivel de experiencia (só para usuarios rexistrados)", "rcfilters-filter-userExpLevel-newcomer-label": "Chegados recentemente", "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edicións e 4 días de actividade.", "rcfilters-filter-userExpLevel-learner-label": "Aprendices", - "rcfilters-filter-userExpLevel-learner-description": "Máis días de actividade e edicións que 'novatos' pero menos que 'usuarios experimentados'.", + "rcfilters-filter-userExpLevel-learner-description": "Máis días de actividade e edicións que \"novatos\" pero menos que \"usuarios experimentados\".", "rcfilters-filter-userExpLevel-experienced-label": "Usuarios experimentados", "rcfilters-filter-userExpLevel-experienced-description": "Máis de 30 días de actividade e 500 edicións.", + "rcfilters-filtergroup-automated": "Contribucións automatizadas", "rcfilters-filter-bots-label": "Bot", + "rcfilters-filter-bots-description": "Edicións realizadas por ferramentas automatizadas.", "rcfilters-filter-humans-label": "Humano (non bot)", + "rcfilters-filter-humans-description": "Edicións realizadas por editores humanos.", "rcfilters-filter-minor-label": "Edicións menores", "rcfilters-filter-minor-description": "Edicións que o autor etiquetou como menores.", + "rcfilters-filter-major-label": "Edicións non menores", "rcfilters-filtergroup-changetype": "Tipo de cambio", "rcfilters-filter-pageedits-label": "Edicións de páxinas", "rcnotefrom": "A continuación {{PLURAL:$5|móstrase o cambio feito|móstranse os cambios feitos}} desde o $3 ás $4 (móstranse $1 como máximo).", diff --git a/languages/i18n/he.json b/languages/i18n/he.json index 2e3a445caf..4b6027e006 100644 --- a/languages/i18n/he.json +++ b/languages/i18n/he.json @@ -1109,8 +1109,8 @@ "editusergroup": "טעינת קבוצות המשתמש", "editinguser": "שינוי ההרשאות של {{GENDER:$1|המשתמש|המשתמשת}} [[User:$1|$1]] $2", "viewinguserrights": "צפייה בהרשאות של {{GENDER:$1|המשתמש|המשתמשת}} [[User:$1|$1]] $2", - "userrights-editusergroup": "עריכת קבוצות משתמש", - "userrights-viewusergroup": "צפייה בקבוצות משתמש", + "userrights-editusergroup": "עריכת קבוצות {{GENDER:$1|המשתמש|המשתמשת}}", + "userrights-viewusergroup": "צפייה בקבוצות {{GENDER:$1|המשתמש|המשתמשת}}", "saveusergroups": "שמירת הקבוצות של ה{{GENDER:$1|משתמש|משתמשת}}", "userrights-groupsmember": "{{GENDER:$2|חבר|חברה}} ב{{PLURAL:$1|קבוצה|קבוצות}}:", "userrights-groupsmember-auto": "{{GENDER:$2|חבר|חברה}} אוטומטית ב{{PLURAL:$1|קבוצה|קבוצות}}:", diff --git a/languages/i18n/hi.json b/languages/i18n/hi.json index f26e1b14d9..6ed288068d 100644 --- a/languages/i18n/hi.json +++ b/languages/i18n/hi.json @@ -1151,6 +1151,7 @@ "userrights-nodatabase": "डाटाबेस $1 या तो मौजूद नहीं है या फिर स्थानीय नहीं है।", "userrights-changeable-col": "समूह जिन्हें आप बदल सकते हैं", "userrights-unchangeable-col": "समूह जिन्हें आप नहीं बदल सकते हैं", + "userrights-expiry-none": "समाप्त नहीं होता", "userrights-conflict": "सदस्य अधिकार बदलावों में अंतर्विरोध! कृपया अपने बदलाव जाँचें और पुनः सुनिश्चित करें।", "group": "समूह:", "group-user": "सदस्य", @@ -1319,7 +1320,7 @@ "action-userrights-interwiki": "अन्य विकियों पर सदस्य अधिकार बदलने", "action-siteadmin": "डाटाबेस को ताला लगाने या खोलने", "action-sendemail": "ई-मेल भेजने", - "action-editmyoptions": "अपनी पसंदें संपादित करें", + "action-editmyoptions": "अपनी पसंद संपादित करें", "action-editmywatchlist": "ध्यानसूची सम्पादित करने", "action-viewmywatchlist": "अपनी ध्यानसूची देखें", "action-viewmyprivateinfo": "अपनी व्यक्तिगत जानकारी देखने", diff --git a/languages/i18n/hr.json b/languages/i18n/hr.json index a66ea05d1c..11bcf00ab8 100644 --- a/languages/i18n/hr.json +++ b/languages/i18n/hr.json @@ -585,7 +585,7 @@ "changeemail-newemail-help": "Ako želite izbrisati adresu Vaše e-pošte, ostavite ovo polje praznim. U tom slučaju, nećete biti u mogućnosti ponovno postaviti zaboravljenu zaporku i nećete moći primati e-poštu s ovog wikija.", "changeemail-none": "(ništa)", "changeemail-password": "Zaporka za projekt {{SITENAME}}:", - "changeemail-submit": "Promijeni E-mail", + "changeemail-submit": "Promijeni e-mail", "changeemail-throttled": "Nedavno ste se previše puta pokušali prijaviti.\nMolimo Vas pričekajte $1 prije nego što pokušate ponovno.", "bold_sample": "Podebljani tekst", "bold_tip": "Podebljani tekst", @@ -3299,6 +3299,7 @@ "log-action-filter-rights-autopromote": "automatska promjena", "log-action-filter-upload-upload": "novo postavljanje", "log-action-filter-upload-overwrite": "ponovno postavljanje", + "authmanager-provider-password": "Autorizacija zaporkom", "authmanager-provider-temporarypassword": "Privremena zaporka", "changecredentials": "Promjena vjerodajnica", "changecredentials-submit": "Promijeni vjerodajnice", diff --git a/languages/i18n/ie.json b/languages/i18n/ie.json index 7d61ad6463..c2201b1c41 100644 --- a/languages/i18n/ie.json +++ b/languages/i18n/ie.json @@ -440,7 +440,7 @@ "currentrev": "Ultim revision", "currentrev-asof": "Actual version de $2, clocca $3", "revisionasof": "Revision de $1", - "revision-info": "Revision de $1, fabricat de $2:$7", + "revision-info": "Revision de $1, fat de $2:$7", "previousrevision": "← Anteyan version", "nextrevision": "Revision sequent →", "currentrevisionlink": "Ultim revision", @@ -957,7 +957,7 @@ "tooltip-ca-nstab-main": "Vider li articul", "tooltip-ca-nstab-user": "Vider li págine de usator", "tooltip-ca-nstab-media": "Vider li págine de media", - "tooltip-ca-nstab-special": "Ti es un págine special, on ne posse redacter it", + "tooltip-ca-nstab-special": "To es un págine special, on ne posse redacter it", "tooltip-ca-nstab-project": "Vider li págine de projecte", "tooltip-ca-nstab-image": "Vider li págine de figura", "tooltip-ca-nstab-mediawiki": "Vider li missage de sistema", diff --git a/languages/i18n/ko.json b/languages/i18n/ko.json index a3f6370f39..7b5400dfba 100644 --- a/languages/i18n/ko.json +++ b/languages/i18n/ko.json @@ -1146,9 +1146,12 @@ "userrights-nodatabase": "데이터베이스 $1이 존재하지 않거나 로컬에 있지 않습니다.", "userrights-changeable-col": "바꿀 수 있는 권한", "userrights-unchangeable-col": "바꿀 수 없는 권한", + "userrights-expiry-current": "$1에 만료", "userrights-expiry-none": "만료하지 않음", + "userrights-expiry": "기한:", "userrights-expiry-existing": "현재 만료 시간: $2 $3", "userrights-expiry-othertime": "다른 시간:", + "userrights-expiry-options": "1일:1 day,1주일:1 week,1개월:1 month,3개월:3 months,6개월:6 months,1년:1 year", "userrights-invalid-expiry": "그룹 \"$1\"의 만료 시간이 유효하지 않습니다.", "userrights-expiry-in-past": "그룹 \"$1\"의 만료 시간이 과거입니다.", "userrights-conflict": "사용자 권한 바꾸기가 충돌합니다! 바뀜을 검토하고 확인하세요.", @@ -1903,6 +1906,7 @@ "apisandbox-results-error": "API 질의 응답을 불러오는 도중 오류 발생: $1.", "apisandbox-request-format-url-label": "URL 쿼리 문자열", "apisandbox-request-url-label": "요청 URL:", + "apisandbox-request-json-label": "JSON 요청:", "apisandbox-request-time": "요청 처리 시간: {{PLURAL:$1|$1 ms}}", "apisandbox-results-fixtoken": "토큰 수정 후 다시 제출", "apisandbox-results-fixtoken-fail": "\"$1\" 토크을 가져오는데 실패했습니다.", diff --git a/languages/i18n/nl.json b/languages/i18n/nl.json index 834e1c738b..d964eab009 100644 --- a/languages/i18n/nl.json +++ b/languages/i18n/nl.json @@ -1929,6 +1929,7 @@ "apisandbox-results-error": "Er is een fout opgetreden tijdens het laden van het antwoord op het API-verzoek: $1.", "apisandbox-request-selectformat-label": "Toon resultaat als:", "apisandbox-request-url-label": "Verzoek-URL:", + "apisandbox-request-json-label": "Verzoek JSON:", "apisandbox-request-time": "Doorlooptijd verzoek: {{PLURAL:$1|$1 ms}}", "apisandbox-results-fixtoken": "Token corrigeren en opnieuw verzenden", "apisandbox-results-fixtoken-fail": "Het ophalen van het token van type \"$1\" is mislukt.", diff --git a/languages/i18n/or.json b/languages/i18n/or.json index 545ff6205b..2268dcfa65 100644 --- a/languages/i18n/or.json +++ b/languages/i18n/or.json @@ -14,7 +14,8 @@ "아라", "Macofe", "Nistha.aslp", - "Matma Rex" + "Matma Rex", + "Susant purohit" ] }, "tog-underline": "ଲିଙ୍କତଳେଗାର ଟାଣିବା:", @@ -58,7 +59,7 @@ "tog-showhiddencats": "ଲୁଚାଯାଇଥିବା ଶ୍ରେଣୀଗୁଡ଼ିକ ଦେଖାଇବେ", "tog-norollbackdiff": "ପଛକୁ ଫେରାଇଲାପରେ ତୁଳନା ଦେଖାନ୍ତୁ ନାହିଁ", "tog-useeditwarning": "ଯେତେବେଳେ ମୁଁ ଗୋଟିଏ ସାଇତାଯାଇନଥିବା ପୃଷ୍ଠାକୁ ବନ୍ଦ କରିଦିଏ ମୋତେ ଚେତାବନୀ ଦେବେ", - "tog-prefershttps": "ଲଗ ଇନ କଲାପରେ ସର୍ବଦା ସୁରକ୍ଷିତ କନେକ୍ସନ ବ୍ୟବହାର କରିବେ", + "tog-prefershttps": "ଲଗ ଇନ ହେଲା ପରେ ସର୍ବଦା ସୁରକ୍ଷିତ ସଂଯୋଗ ବ୍ୟବହାର କରିବେ", "underline-always": "ସବୁବେଳେ", "underline-never": "କେବେନୁହେଁ", "underline-default": "ବ୍ରାଉଜର କିମ୍ବା ସ୍କିନରେ ଆଗରୁ ଥିବା ସୁବିଧା", @@ -153,7 +154,7 @@ "newwindow": "(ଏହା ନୂଆ ଉଇଣ୍ଡୋରେ ଖୋଲିବ)", "cancel": "ନାକଚ", "moredotdotdot": "ଅଧିକ...", - "morenotlisted": "ଏହି ତାଲିକା ପୂରା ହୋଇ ନାହିଁ", + "morenotlisted": "ହୁଏତ ଏହି ତାଲିକା ଅସମ୍ପୂର୍ଣ.", "mypage": "ପୃଷ୍ଠା", "mytalk": "ଆଲୋଚନା", "anontalk": "ଆଲୋଚନା", @@ -180,6 +181,7 @@ "searcharticle": "ଯାଆନ୍ତୁ", "history": "ଫାଇଲ ଇତିହାସ", "history_short": "ଇତିହାସ", + "history_small": "ଇତିହାସ", "updatedmarker": "ମୋ ଶେଷ ଆସିବା ପରେ ଅପଡେଟ କରାଯାଇଅଛି", "printableversion": "ଛପାହୋଇପାରିବା ପୃଷ୍ଠା", "permalink": "ସବୁଦିନିଆ ଲିଙ୍କ", @@ -211,6 +213,7 @@ "talk": "ଆଲୋଚନା", "views": "ଦେଖା", "toolbox": "ଉପକରଣ", + "tool-link-emailuser": "{{GENDER:$1|user}}ଙ୍କୁ ଇ-ମେଲ କରନ୍ତୁ", "userpage": "ବ୍ୟବହାରକାରୀଙ୍କ ପୃଷ୍ଠା ଦେଖନ୍ତୁ", "projectpage": "ପ୍ରକଳ୍ପ ପୃଷ୍ଠାଟି ଦେଖାଇବା", "imagepage": "ଫାଇଲ ପୃଷ୍ଠାଗୁଡ଼ିକ ଦେଖନ୍ତୁ", @@ -344,6 +347,11 @@ "badtitletext": "ଆପଣ ଅନୁରୋଧ କରିଥିବା ପୃଷ୍ଠାଟି ଭୁଲ, ଖାଲି ଅଛି ବା ବାକି ଭାଷା ସାଙ୍ଗରେ ଭୁଲରେ ଯୋଡ଼ା ଯାଇଛି ବା ଭୁଲ ଇଣ୍ଟର ଉଇକି ନାମ ଦିଆଯାଇଛି ।\nଏଥିରେ ଥିବା ଗୋଟିଏ ବା ଦୁଇଟି ଅକ୍ଷର ଶିରୋନାମା ଭାବରେ ବ୍ୟବହାର କରାଯାଇ ପାରିବ ନାହିଁ ।", "title-invalid-empty": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠାର ଶର୍ଷକଟି ଖାଲି ଅଛି କିମ୍ବା ନେମସ୍ପସର ନାମ ଅଛି ।", "title-invalid-utf8": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠାର ଶର୍ଷକରେ ଅବୈଧ UTF-8 ଧାରା ଅଛି ।", + "title-invalid-interwiki": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠା ଶିରୋନାମା ରେ ଇଣ୍ଟରଉଇକି ଲିଙ୍କ ରହିଥିବାରୁ ଏହି ଶିରୋନାମା ରେ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ।", + "title-invalid-talk-namespace": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠା ଶିରୋନାମା ଏକ ଟକ ପୃଷ୍ଠା କୁ ଆଧାର କରେ ଯାହା ଉପଲବ୍ଧ ନୁହେଁ।", + "title-invalid-characters": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠା ଶିରୋନାମା ଏକ ଅଗ୍ରହଣୀୟ ଚରିତ୍ର \"$1\" ରହିଛି।", + "title-invalid-magic-tilde": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷା ଶିରୋନାମା ରେ ଅଗ୍ରହଣୀୟ ମେଜିକ ଟିଲଡ଼େ ଅନୁକ୍ରମ (~~~)ରହିଛି।", + "title-invalid-leading-colon": "ଅନୁରୋଧ କରାଯାଇଥିବା ପ୍ରୁଷ୍ଠା ଶିରୋନାମାର ଆରମ୍ଭ ରେ ଏକ ଅଗ୍ରହଣୀୟ କୋଲନ ରହିଛି।", "perfcached": "ତଳଲିଖିତ ତଥ୍ୟଗୁଡିକୁ ଅସ୍ଥାୟୀ ଭାବେ ରଖାଗଲା ଏବଂ ଏହା ଅପଡେଟ ନ ହୋଇପାରେ । ଅତିବେଶିରେ {{PLURAL:$1|ଫଳ|$1ଫଳଗୁଡିକ }} ଅସ୍ଥାୟୀ ରୂପେ ରହି ପାରିବ ।", "perfcachedts": "ତଳଲିଖିତ ତଥ୍ୟଗୁଡିକୁ ଅସ୍ଥାୟୀ ଭାବେ ରଖାଗଲା ଏବଂ $1ରେ ଶେଷଥର ଅପଡେଟ ହୋଇଥିଲା । ଅତିବେଶିରେ {{PLURAL:$1|ଫଳ|$1ଫଳଗୁଡିକ }} ଅସ୍ଥାୟୀ ରୂପେ ରହି ପାରିବ ।", "querypage-no-updates": "ଏହି ପୃଷ୍ଠାଟି ପାଇଁ ଅପଡେଟସବୁ ଏବେ ଅଚଳ କରାଯାଇଅଛି ।\nଏଠାରେ ଥିବା ତଥ୍ୟ ସବୁ ଏବେ ସତେଜ ହୋଇପାରିବ ନାହିଁ ।", @@ -394,12 +402,17 @@ "createacct-yourpasswordagain-ph": "ଆଉଥରେ ପାସୱାର୍ଡ଼ ଦିଅନ୍ତୁ", "userlogin-remembermypassword": "ମୋତେ ଲଗ-ଇନ କରି ରଖିଥାନ୍ତୁ", "userlogin-signwithsecure": "ନିରାପଦ କନେକସନ ବ୍ୟବ‌ହାର କରନ୍ତୁ", + "cannotlogin-title": "ଲଗ ଇନ ହୋଇପାରିବ ନାହିଁ", + "cannotlogin-text": "ଲଗିଂ ଇନ ସମ୍ଭବ ନୁହେଁ।", "cannotloginnow-title": "ଏବେ ଲଗ ଇନ ହୋଇପାରିବ ନାହିଁ", "cannotloginnow-text": "$1ବ୍ୟବହାର କରୁଥିବା ବେଳେ ଲଗ ଇନ ହେଇପାରିବ ନାହିଁ ।", + "cannotcreateaccount-title": "ଖାତା ତିଆରି କରାଯାଇପାରିବ ନାହିଁ", + "cannotcreateaccount-text": "ସିଧାସଳଖ ଖାତା ଖୋଲିବା ଏହି ଉଇକି ରେ ସମର୍ଥ କରାଯାଇ ନାହିଁ।", "yourdomainname": "ଆପଣଙ୍କ ଡୋମେନ:", "password-change-forbidden": "ଆପଣ ଏହି ଉଇକିରେ ପାସୱାର୍ଡ ବଦଳାଇ ପାରିବେ ନାହିଁ ।", "externaldberror": "ବୋଧ ହୁଏ ଚିହ୍ନଟ ଡାଟାବେସ ଭୁଲଟିଏ ହୋଇଥିଲା ବା ଆପଣଙ୍କୁ ନିଜର ବାହାର ଖାତା ଅପଡେଟ କରିବା ନିମନ୍ତେ ଅନୁମତି ମିଳିନାହିଁ ।", "login": "ଲଗ-ଇନ (Log in)", + "login-security": "ଆପଣଙ୍କ ପରିଚୟ ଯାଞ୍ଚ କରନ୍ତୁ", "nav-login-createaccount": "ଲଗ ଇନ /ନୂଆ ଖାତା ଖୋଲନ୍ତୁ", "userlogin": "ଲଗ ଇନ /ନୂଆ ଖାତା ଖୋଲନ୍ତୁ", "userloginnocreate": "ଲଗ-ଇନ (Log in)", @@ -417,18 +430,23 @@ "userlogin-resetpassword-link": "ପାସୱାର୍ଡ଼ ମନେପଡୁନାହିଁ?", "userlogin-helplink2": "ଲଗ ଇନ ପାଇଁ ସହଯୋଗ କରନ୍ତୁ", "userlogin-loggedin": "ଆପଣ {{GENDER:$1|$1}} ନାମରେ ଲଗ ଇନ କରିଛନ୍ତି । ତଳ ଫର୍ମଟି ବ୍ୟବହାର କରି ଆଉ ଜଣେ ସଭ୍ୟ ଭାବେ ଲଗ ଇନ କରନ୍ତୁ ।", + "userlogin-reauth": "ଆପଣ {{GENDER:$1|$1}} ବୋଲି ଯାଞ୍ଚ କରିବା ପାଇଁ ଆପଣଙ୍କୁ ଆଉଥରେ ଲଗ ଇନ କରିବାକୁ ହେବ।", "userlogin-createanother": "ଆଉ ଏକ ଖାତା ତିଆରି କରନ୍ତୁ", "createacct-emailrequired": "ଇମେଲ ଠିକଣା", "createacct-emailoptional": "ଇମେଲ ଠିକଣା (ଇଚ୍ଛାଧୀନ)", "createacct-email-ph": "ଆପଣଙ୍କ ଇମେଲ ଠିକଣା ଦିଅନ୍ତୁ", "createacct-another-email-ph": "ଆପଣଙ୍କ ଇ-ମେଲ ଠିକଣା ଦିଅନ୍ତୁ", "createaccountmail": "ଏକ ଅସ୍ଥାୟୀ ପାସୱାର୍ଡ଼ ବ୍ୟବହାର କରନ୍ତୁ ଏବଂ ଏହାକୁ ତଳେ ଦିଆଯାଇଥିବା ଇ-ମେଲ ଠିକଣାକୁ ପଠାଇଦିଅନ୍ତୁ", + "createaccountmail-help": "ପାସୱାର୍ଡ ନ ଜାଣି ମଧ୍ୟ ଆଉ ଜଣେ ବ୍ୟକ୍ତି ଙ୍କ ପାଇଁ ଖାତା ଖୋଲିବାକୁ ବ୍ୟବହାର କରାଯାଇପାରିବ।", "createacct-realname": "ପ୍ରକୃତ ନାମ (ଇଚ୍ଛାଧୀନ)", "createaccountreason": "କାରଣ:", "createacct-reason": "କାରଣ", "createacct-reason-ph": "ଆପଣ ଅନ୍ୟଏକ ଖାତା କାହିଁକି ତିଆରି କରୁଛନ୍ତି", + "createacct-reason-help": "ଖାତା ଖୋଲିବା ଲଗ ରେ ବାର୍ତା ଦେଖାଯାଇଛି", "createacct-submit": "ନିଜର ନୂଆ ଖାତାଟିଏ ଖୋଲନ୍ତୁ", "createacct-another-submit": "ଆଉ ଏକ ଖାତା ଖୋଲନ୍ତୁ", + "createacct-continue-submit": "ଖାତା ଖୋଲିବା ଜାରି ରଖନ୍ତୁ", + "createacct-another-continue-submit": "ଖାତା ଖୋଲିବା ଜାରି ରଖନ୍ତୁ", "createacct-benefit-heading": "{{SITENAME}} ଆପଣଙ୍କ ଭଳି ଲୋକମାନଙ୍କ ଦ୍ୱାରା ଗଢ଼ା ।", "createacct-benefit-body1": "{{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନାମାନ}}", "createacct-benefit-body2": "{{PLURAL:$1|ପୃଷ୍ଠା|ପୃଷ୍ଠାମାନ}}", @@ -442,6 +460,7 @@ "nocookiesnew": "ଇଉଜର ନାମଟି ତିଆରି କରିଦିଆଗଲା, ହେଲେ ଆପଣ ଲଗ ଇନ କରିନାହାନ୍ତି ।\n{{SITENAME}} ସଭ୍ୟମାନଙ୍କୁ ଲଗ ଇନ କରିବା ନିମନ୍ତେ କୁକି ବ୍ୟବହାର କରିଥାଏ । ଆପଣଙ୍କ କୁକି ଅଚଳ କରାଯାଇଅଛି ।\nଦୟାକରି ତାହାକୁ ସଚଳ କରନ୍ତୁ ଓ ତାହା ପରେ ଆପଣଙ୍କ ନୂଆ ଇଉଜର ନାମ ଓ ପାସୱାର୍ଡ଼ ସହିତ ଲଗ ଇନ କରନ୍ତୁ ।", "nocookieslogin": "{{SITENAME}} ସଭ୍ୟ ମାନଙ୍କୁ ଲଗ ଇନ କରାଇବା ପାଇଁ କୁକି ବ୍ୟବହାର କରିଥାଏ ।\nଆପଣଙ୍କର କୁକି ଅଚଳ ହୋଇଅଛି ।\nଦୟାକରି ତାହାକୁ ସଚଳ କରି ଆଉଥରେ ଚେଷ୍ଟା କରନ୍ତୁ ।", "nocookiesfornew": "ଯେହେତୁ ଆମ୍ଭେ ଏହାର ମୂଳାଧାର ଜାଣିପାରିଲୁ ନାହିଁ ଏହି ଇଉଜର ଖାତାଟି ତିଆରି କରାଗଲା ନାହିଁ ।\nଥୟ କରନ୍ତୁ କି ଆପଣ କୁକି ସଚଳ କରିଅଛନ୍ତି, ପୃଷ୍ଠାଟିକୁ ଆଉଥରେ ଲୋଡ଼ କରି ଚେଷ୍ଟା କରନ୍ତୁ ।", + "createacct-loginerror": "ଖାତା ସଫଳ ଭାବରେ ଖୋଲା ଗଲା କିନ୍ତୁ ଆପଣଙ୍କୁ ସ୍ଵତଃ ଲଗ ଇନ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି [[Special:UserLogin|manual login]] କୁ ଦେଖନ୍ତୁ।", "noname": "ଆପଣ ଗୋଟିଏ ବୈଧ ଇଉଜର ନାମ ଦେଇନାହାନ୍ତି ।", "loginsuccesstitle": "ଠିକଭାବେ ଲଗ-ଇନ ହେଲା", "loginsuccess": "'''ଆପଣ {{SITENAME}}ରେ \"$1\" ନାମରେ ଲଗ-ଇନ କରିଛନ୍ତି ।'''", @@ -453,6 +472,7 @@ "wrongpasswordempty": "ଦିଆଯାଇଥିବା ପାସବାର୍ଡ଼ଟି ଖାଲି ଛଡ଼ାଯାଇଛି ।\nଦୟାକରି ଆଉଥରେ ଚେଷ୍ଟା କରନ୍ତୁ ।", "passwordtooshort": "ପାସୱାର୍ଡ଼ଟି ଅତି କମରେ {{PLURAL:$1|ଗୋଟିଏ ଅକ୍ଷର|$1ଟି ଅକ୍ଷର}}ର ହୋଇଥିବା ଲୋଡ଼ା ।", "passwordtoolong": "ପସସ୍ୱାର୍ଡଟି {{PLURAL:$1|1 ଅକ୍ଷର|$1 ଅକ୍ଷରଗୁଡିକ}}ଠାରୁ ଅଧିକ ହୋଇ ପାରିବ ନାହିଁ ।", + "passwordtoopopular": "ସାଧାରଣ ଭାବରେ ବଛାଯାଇଥିବା ପାସୱାର୍ଡ ବ୍ୟବହାର କରିହେବ ନାହିଁ। ଦୟାକରି ଏକ ଅଦ୍ଵିତୀୟ ପାସୱାର୍ଡ ବାଛନ୍ତୁ।", "password-name-match": "ଆପଣଙ୍କ ପାସୱାର୍ଡ଼ଟି ଆପଣଙ୍କ ଇଉଜର ନାମ ଠାରୁ ଅଲଗା ହେବା ଉଚିତ ।", "password-login-forbidden": "ଏହି ଇଉଜର ନାମ ଓ ପାସୱାର୍ଡ଼ର ବ୍ୟବହାରକୁ ବାରଣ କରାଯାଇଅଛି ।", "mailmypassword": "ପାସୱାର୍ଡ଼ଟି ରିସେଟ କରିବେ", @@ -465,7 +485,7 @@ "eauthentsent": "ଆପଣ ଦେଇଥିବା ଇ-ମେଲ ଠିକଣାକୁ ଏକ ମେଲଟିଏ ପଠାଗଲା ।\nଆହୁରି ଅଧିକ ଇ-ମେଲ ଆପଣଙ୍କ ଖାତାକୁ ପଠାହେବା ଆଗରୁ, ଏହି ଖାତାଟି ନିଜର ବୋଲି ଥୟ କରିବା ପାଇଁ ପଠାଯାଇଥିବା ଇ-ମେଲରେ ଥିବା ସୂଚନା ଅନୁସାରେ କାମ କରନ୍ତୁ ।", "throttled-mailpassword": "ଗତ {{PLURAL:$1|ଏକ ଘଣ୍ଟାରେ|$1 ଘଣ୍ଟାରେ}} ଆପଣଙ୍କୁ ଏକ ପୁନଃସ୍ଥାପନ ଇମେଲଟିଏ ପଠାଯାଇଛି ।\nଅବ୍ୟବହାରକୁ ରୋକିବା ନିମନ୍ତେ, {{PLURAL:$1|ଏକ ଘଣ୍ଟାରେ|$1 ଘଣ୍ଟାରେ}} କେବଳ ଗୋଟିଏ ଇମେଲ ହିଁ ପଠାହେବ ।", "mailerror": "ମେଲ ପଠାଇବାରେ ଭୁଲ : $1", - "acct_creation_throttle_hit": "ଏହି ଉଇକିର ଦେଖଣାହାରୀ ମାନେ ଆପଣଙ୍କ IP ଠିକଣା ବ୍ୟବହାର କରି ବିଗତ ଦିନରେ {{PLURAL:$1|ଖାତାଟିଏ|$1 ଗୋଟି ଖାତା}} ତିଆରି କରିଛନ୍ତି ଯାହା ସେହି ସମୟସୀମା ଭିତରେ ସବୁଠାରୁ ଅଧିକ ଥିଲା ।\nତେଣୁ, ଏହି IP ଠିକଣାର ଦେଖଣାହାରୀ ଗଣ ଏବେ ଆଉ ଅଧିକ ଖାତା ଖୋଲିପାରିବେ ନାହିଁ ।", + "acct_creation_throttle_hit": "ଏହି ଉଇକିର ଦେଖଣାହାରୀ ମାନେ ଆପଣଙ୍କ IP ଠିକଣା ବ୍ୟବହାର କରି ବିଗତ $2 ରେ {{PLURAL:$1|ଖାତାଟିଏ|$1 ଗୋଟି ଖାତା}} ତିଆରି କରିଛନ୍ତି ଯାହା ସେହି ସମୟସୀମା ଭିତରେ ସବୁଠାରୁ ଅଧିକ ଥିଲା ।\nତେଣୁ, ଏହି IP ଠିକଣାର ଦେଖଣାହାରୀ ଗଣ ଏବେ ଆଉ ଅଧିକ ଖାତା ଖୋଲିପାରିବେ ନାହିଁ ।", "emailauthenticated": "$2 ତାରିଖ $3 ଘଟିକା ସମୟରେ ଆପଣଙ୍କ ଇ-ମେଲ ଠିକଣାଟି ଥୟ ହେଲା ।", "emailnotauthenticated": "ଆପଣଙ୍କ ଇ-ମେଲ ଠିକଣାଟି ଏ ଯାଏ ଥୟ ହୋଇନାହିଁ ।\nଏହି ସବୁ ସୁବିଧାକୁ ନେଇ ଆପଣଙ୍କୁ କୌଣସି ଇ-ମେଲ ପଠାଯିବ ନାହିଁ ।", "noemailprefs": "ଆପଣଙ୍କ ପସନ୍ଦ ଭିତରେ ଏକ ଇ-ମେଲ ଠିକଣା ଦିଅନ୍ତୁ ଯାହା ଏହି ସବୁ ସୁବିଧାକୁ ସଚଳ କରାଇବ ।", @@ -485,6 +505,7 @@ "createacct-another-realname-tip": "ପ୍ରକୃତ ନାମ ଦେବା ଆପଣଙ୍କ ଉପରେ ନିର୍ଭର କରେ ।\nଯଦି ଆପଣ ଏହା ଦିଅନ୍ତି, ତେବେ ଏହା ଆପଣଙ୍କ କାମ ପାଇଁ ଶ୍ରେୟ ଦେବାରେ ବ୍ୟବହାର କରାଯାଇପାରିବ ।", "pt-login": "ଲଗ-ଇନ", "pt-login-button": "ଲଗ-ଇନ", + "pt-login-continue-button": "ଲଗଇନ ଜାରି ରଖନ୍ତୁ", "pt-createaccount": "ଖାତାଟିଏ ଖୋଲନ୍ତୁ", "pt-userlogout": "ଲଗ-ଆଉଟ", "php-mail-error-unknown": "PHP ର ମେଲ() କାମରେ ଅଜଣା ଅସୁବିଧା ।", @@ -500,12 +521,18 @@ "changepassword-success": "ଆପଣଙ୍କ ପାସୱାର୍ଡ଼ଟି ସଫଳତା ପୂର୍ବକ ବଦଳାଇ ଦିଆଗଲା !", "changepassword-throttled": "ଆପଣ ନିକଟରେ ଖୁବ ଅଧିକ ଥର ଲଗ ଇନ କରିବାକୁ ଚେଷ୍ଟା କରିଛନ୍ତି ।\nଆଉ ଅଧିକ ଥର ଚେଷ୍ଟା କରିବା ଆଗରୁ ଦୟାକରି $1 ପାଇଁ ଅପେକ୍ଷା କରନ୍ତୁ ।", "botpasswords": "ବଟ ପାସୱାର୍ଡ଼", + "botpasswords-disabled": "Bot ପାସୱାର୍ଡ ଅକାମି କରାଯାଇଛି।", + "botpasswords-no-central-id": "Bot ପାସୱାର୍ଡ ବ୍ୟବହାର କରିବାକୁ ଆପଣ ନିଶ୍ଚୟ ଏକ କେନ୍ଦ୍ରୀକୃତ ଖାତା ରେ ଲଗ ଇନ ହେଇଥିବାକୁ ହେବ।", "botpasswords-label-appid": "ବଟ ନାମ:", "botpasswords-label-create": "ତିଆରି କରିବେ", "botpasswords-label-update": "ଅପଡେଟ କରିବେ", "botpasswords-label-cancel": "ବାତିଲ", "botpasswords-label-delete": "ଲିଭାଇବେ", "botpasswords-label-resetpassword": "ପାସୱାର୍ଡ଼ଟି ରିସେଟ କରିବେ", + "botpasswords-bad-appid": "Bot ନାମ \"$1\"ବୈଧ ନୁହେଁ।", + "botpasswords-insert-failed": "Bot ନାମ \"$1\" ଯୋଗ କରାଯାଇ ପାରିଲା ନାହିଁ। ଏହା ଆଗରୁ ଯୋଗ ହେଇଥିଲା କି?", + "botpasswords-update-failed": "ବୋଟ ନାମ \"$1\" ଅଧୁନାତନ ହେଇପାରିଲା ନାହିଁ। ଏହା ଲିଭାଇ ଦିଆଯାଇଥିଲା କି ?", + "botpasswords-created-title": "Bot ପାସୱାର୍ଡ ତିଆରି ହେଲା", "resetpass_forbidden": "ପାସୱାର୍ଡ଼ମାନ ବଦଳା ଯାଇପାରିବ ନାହିଁ", "resetpass-no-info": "ଏହି ପୃଷ୍ଠାଟିକୁ ସିଧା ଖୋଲିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଲଗ ଇନ କରିବାକୁ ପଡ଼ିବ ।", "resetpass-submit-loggedin": "ପାସୱାର୍ଡ଼ ବଦଳାନ୍ତୁ", @@ -3038,45 +3065,12 @@ "feedback-thanks-title": "ସାଧୁବାଦ!", "searchsuggest-search": "ଖୋଜନ୍ତୁ", "searchsuggest-containing": "ଖୋଜୁଛି...", - "api-error-badaccess-groups": "ଆପଣଙ୍କୁ ଏହି ଉଇକିରେ ଅପଲୋଡ଼ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇନାହିଁ ।", "api-error-badtoken": "ଭିତର ଅସୁବିଧା: ଖରାପ ଟୋକନ ।", - "api-error-copyuploaddisabled": "URL ଦେଇ ଅପଲୋଡ଼ କରିବା ଏହି ସର୍ଭରରେ ଅଚଳ କରାଯାଇଅଛି ।", - "api-error-duplicate": "ଏହି ସାଇଟରେ ସେହି ଏକା ତଥ୍ୟ ଥିବା {{PLURAL:$1| ଆଉ ଏକ ଫାଇଲ ରହିଅଛି|ଆଉ କିଛି ଫାଇଲ ରହି ଅଛନ୍ତି}} ।", - "api-error-duplicate-archive": "ସେହି ସାଇଟରେ ସେହି ଏକା ଭିତର ଭାଗ ସହିତ ଆଗରୁ {{PLURAL:$1|ଆଉ ଫାଇଲଟିଏ ଥିଲା|ଆଉ କେତେକ ଫାଇଲ ଥିଲା}}, କିନ୍ତୁ {{PLURAL:$1|ତାହାକୁ|ସେସବୁକୁ}} ଲିଭାଇ ଦିଆଯାଇଅଛି ।", - "api-error-empty-file": "ଆପଣ ପଠାଇଥିବା ଫାଇଲଟି ଖାଲି ଅଟେ ।", "api-error-emptypage": "ନୂଆ, ଖାଲି ପୃଷ୍ଠ ତିଆରି କରିବାର ଅନୁମତି ନାହି ।", - "api-error-fetchfileerror": "ଭିତର ଅସୁବିଧା: ଏହି ଫାଇଲଟି ପାଖରେ ପହଞ୍ଚିବା ବେଳେ କିଛି ଅସୁବିଧା ହେଲା ।", - "api-error-fileexists-forbidden": "\"$1\" ନାମରେ ଗୋଟିଏ ଫାଇଲ ଆଗରୁ ଅଛି, ଏବଂ ଏହା ଉପରେ ଲେଖି ହେବନି ।", - "api-error-fileexists-shared-forbidden": "\"$1\" ନାମରେ ଗୋଟିଏ ଫାଇଲ ବଣ୍ଟାଯାଇଥିବା ସାଇତାଗୃହରେ ଅଛି, ଏବଂ ଏହା ବାଲାଯାଇପାରିବ ନାହିଁ ।", - "api-error-file-too-large": "ଆପଣ ପଠାଇଥିବା ଫାଇଲଟି ବିରାଟ ଅଟେ ।", - "api-error-filename-tooshort": "ଫାଇଲ ନାମଟି ଖୁବ ଛୋଟ ।", - "api-error-filetype-banned": "ଏହି ପ୍ରକାରର ଫାଇଲ ବାରଣ କରାଯାଇଅଛି ।", - "api-error-filetype-banned-type": "$1 {{PLURAL:$4|ଏକ ଅନୁମୋଦିତ ଫାଇଲ ପ୍ରକାର ନୁହେଁ|ମାନ ଅନୁମୋଦିତ ଫାଇଲ ପ୍ରକାର ନୁହଁନ୍ତି}} ।\nଅନୁମୋଦିତ {{PLURAL:$3|ଫାଇଲ ପ୍ରକାର ହେଲା|ଫାଇଲଗୁଡିକର ପ୍ରକାର ହେଲା}} $2 ।", - "api-error-filetype-missing": "ଫାଇଲଟିର ଏକ୍ସଟେନସନ ନାହିଁ ।", - "api-error-hookaborted": "ଏକ ଏକ୍ସଟେନସନ ହୁକ ଦେଇ ଆପଣ କରୁଥିବା ବଦଳଟି ବନ୍ଦ କରିଦିଆଗଲା ।", - "api-error-http": "ଭିତର ଅସୁବିଧା: ସର୍ଭର ସହ ଯୋଡ଼ି ହେଉନାହିଁ ।", - "api-error-illegal-filename": "ଏହି ଫାଇଲ ନାମଟି ଅନୁମୋଦିତ ନୁହେଁ ।", - "api-error-internal-error": "ଆଭ୍ୟନ୍ତରୀଣ ଅସୁବିଧା: ଏହି ଉଇକିରେ ଆପଣଙ୍କ ଅପଲୋଡ଼ କରିବା କାଳରେ କିଛି ଅସୁବିଧା ଘଟିଲା ।", - "api-error-invalid-file-key": "ଭିତର ଅସୁବିଧା: ଫାଇଲଟି ଅସ୍ଥାୟୀ ସାଇତାଘର ଭିତରୁ ମିଳିଲାନାହିଁ ।", - "api-error-missingparam": "ଭିତର ଅସୁବିଧା: ହଜିଯାଇଥିବା ପାରାମିଟର ସବୁକୁ ଅନୁରୋଧ କ୍ରମେ ଦେଖାଇଦିଆଗଲା ।", - "api-error-missingresult": "ଭିତର ଅସୁବିଧା: ନକଲ କରିବା ଠିକରେ ହେଲାକି ନାହିଁ ଜାଣି ପାରିଲା ନାହିଁ ।", - "api-error-mustbeloggedin": "ଫାଇଲ ଅପଲୋଡ଼ କରିବା ନିମନ୍ତେ ଆପଣଙ୍କୁ ଲଗ ଇନ କରିବାକୁ ପଡ଼ିବ ।", - "api-error-mustbeposted": "ଭିତର ଅସୁବିଧା: କରାଯାଇଥିବା ଅନୁରୋଧ ପାଇଁ HTTP POST ଦରକାର ।", - "api-error-noimageinfo": "ଅପଲୋଡ଼ ସଫଳ ହେଲା, କିନ୍ତୁ ସର୍ଭରଟି ଆମ୍ଭଙ୍କୁ ଫାଇଲଟୀ ବାବଦରେ କିଛି ବିବରଣୀ ଦେଲା ନାହିଁ ।", - "api-error-nomodule": "ଭିତର ଅସୁବିଧା: ଅପଲୋଡ଼ ମୋଡୁଲ ଠିକ କରାଯାଇନାହିଁ ।", - "api-error-ok-but-empty": "ଭିତର ଅସୁବିଧା: ସର୍ଭର ଠାରୁ କିଛି ଖବର ନାହିଁ ।", - "api-error-overwrite": "ଆଗରୁଥିବା ଏକ ଫାଇଲ ଉପରେ ମଡ଼ାଇବା ଅନୁମୋଦିତ ନୁହେଁ ।", - "api-error-stashfailed": "ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ସାଇତି ପାରିଲା ନାହିଁ ।", "api-error-publishfailed": "ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ପ୍ରକାଶ କରିପାରିଲା ନାହିଁ ।", - "api-error-stasherror": "ଫାଇଲଟିକୁ ଷ୍ଟାସରେ ଅପଲୋଡ଼ କଲାବେଳେ ତ୍ରୁଟିଟିଏ ପରିଲକ୍ଷିତ ହେଲା ।", - "api-error-timeout": "ସର୍ଭର ଏକ ସୀମିତ କାଳ ଭିତରେ ଉତ୍ତର ଦେଲାନାହିଁ ।", - "api-error-unclassified": "ଏକ ଅଜଣା ଅସୁବିଧା ଘଟିଲା ।", - "api-error-unknown-code": "ଅଜଣା ତୃଟି: \"$1\"", - "api-error-unknown-error": "ଆଭ୍ୟନ୍ତରୀଣ ଅସୁବିଧା: ଫାଇଲଟି ଅପଲୋଡ଼ କରିବା କାଳରେ କିଛି ଅସୁବିଧା ଘଟିଲା ।", + "api-error-stashfailed": "ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ସାଇତି ପାରିଲା ନାହିଁ ।", "api-error-unknown-warning": "ଅଜଣା ଚେତାବନୀ: $1", "api-error-unknownerror": "ଅଜଣା ତୃଟି: \"$1\"", - "api-error-uploaddisabled": "ଉଇକିରେ ଅପଲୋଡ଼ କରିବା ଅଚଳ କରାଯାଇଅଛି ।", - "api-error-verification-error": "ଏହି ଫାଇଲଟି ବୋଧ ହୁଏ ନଷ୍ଟ ହୋଇଯାଇଅଛି କିମ୍ବା ଭୁଲ ଏକ୍ସଟେନସନ ଦିଆଯାଇଅଛି ।", "duration-seconds": "$1 {{PLURAL:$1|ସେକଣ୍ଡ|ସେକେଣ୍ଡ}}", "duration-minutes": "$1 {{PLURAL:$1|ମିନିଟ|ମିନିଟ}}", "duration-hours": "$1 {{PLURAL:$1|ଘଣ୍ଟା|ଘଣ୍ଟା}}", diff --git a/languages/i18n/pl.json b/languages/i18n/pl.json index 4016aacce3..48acf7c3d7 100644 --- a/languages/i18n/pl.json +++ b/languages/i18n/pl.json @@ -2038,7 +2038,7 @@ "emailccsubject": "Kopia Twojej wiadomości do $1: $2", "emailsent": "Wiadomość została wysłana", "emailsenttext": "Twoja wiadomość została wysłana.", - "emailuserfooter": "Ten e-mail został {{GENDER:$1|wysłany}} z {{GRAMMAR:D.lp|{{SITENAME}}}} do {{GENDER:$2|$2}} przez $1 przy użyciu funkcji „{{int:emailuser}}”. Jeśli {{GENDER:$2|Twoja}} odpowiedź na ten e-mail zostanie wysłana do {{GENDER:$1|oryginalnego nadawcy}}, wówczas {{GENDER:$2|Twój}} adres e-mail zostanie {{GENDER:$1|mu|jej}} ujawniony.", + "emailuserfooter": "Ten e-mail został {{GENDER:$1|wysłany}} z {{GRAMMAR:D.lp|{{SITENAME}}}} do {{GENDER:$2|$2}} przez $1 przy użyciu funkcji „{{int:emailuser}}”. Jeśli wyślesz odpowiedź na ten e-mail do {{GENDER:$1|oryginalnego nadawcy}}, wówczas {{GENDER:$2|Twój}} adres e-mail zostanie {{GENDER:$1|mu|jej}} ujawniony.", "usermessage-summary": "Pozostawianie komunikatu systemowego.", "usermessage-editor": "Nadawca komunikatów systemowych", "watchlist": "Obserwowane", diff --git a/languages/i18n/pt-br.json b/languages/i18n/pt-br.json index a57aeaf84a..8903fd9e95 100644 --- a/languages/i18n/pt-br.json +++ b/languages/i18n/pt-br.json @@ -105,7 +105,8 @@ "Bruno.S.Alves 270", "!Silent", "Joao Xavier", - "Nahime2015" + "Nahime2015", + "Alex Great" ] }, "tog-underline": "Sublinhar links:", @@ -766,7 +767,7 @@ "userpage-userdoesnotexist": "A conta \"$1\" não se encontra registrada.\nVerifique se deseja mesmo criar/editar esta página.", "userpage-userdoesnotexist-view": "A conta de usuário \"$1\" não está registrada.", "blocked-notice-logextract": "Este usuário está atualmente bloqueado.\nO registro de bloqueio mais recente é fornecido abaixo, para referência:", - "clearyourcache": "Nota: Após salvar, você pode ter que limpar o \"cache\" do seu navegador para ver as alterações.\n*Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)\n*Google Chorme: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)\n* Internet Explorer: PressioneCtrl enquanto clica Recarregar, ou Pressione Ctrl-F5\n* Opera: Vá para Menu → Configurações (Opera → Preferencias no Mac) e depois para Privacidade e Segurança → Limpar dados de navegação → Imagens e arquivos em cache.", + "clearyourcache": "Nota: Após salvar, você pode ter que limpar o \"cache\" do seu navegador para ver as alterações.\n*Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)\n*Google Chrome: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)\n* Internet Explorer: PressioneCtrl enquanto clica Recarregar, ou Pressione Ctrl-F5\n* Opera: Vá para Menu → Configurações (Opera → Preferencias no Mac) e depois para Privacidade e Segurança → Limpar dados de navegação → Imagens e arquivos em cache.", "usercssyoucanpreview": "'''Dica:''' Utilize o botão \"{{int:showpreview}}\" para testar seu novo CSS antes de salvar.", "userjsyoucanpreview": "'''Dica:''' Utilize o botão \"{{int:showpreview}}\" para testar seu novo JavaScript antes de salvar.", "usercsspreview": "'''Lembre-se de que você está apenas previsualizando o seu CSS particular.'''\n'''Ele ainda não foi salvo!'''", diff --git a/languages/i18n/pt.json b/languages/i18n/pt.json index eb93915e0e..1fdcc8e2a0 100644 --- a/languages/i18n/pt.json +++ b/languages/i18n/pt.json @@ -1163,8 +1163,8 @@ "userrights-expiry-existing": "Prazo de expiração: $3, $2", "userrights-expiry-othertime": "Outra duração:", "userrights-expiry-options": "1 dia:1 day,1 semana:1 week,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year", - "userrights-invalid-expiry": "O tempo de expiração para o grupo \"$1\" é inválido.", - "userrights-expiry-in-past": "O tempo de expiração para o grupo \"$1\" está no passado.", + "userrights-invalid-expiry": "O prazo de expiração para o grupo \"$1\" é inválido.", + "userrights-expiry-in-past": "O prazo de expiração para o grupo \"$1\" está no passado.", "userrights-conflict": "Conflito entre alterações de privilégios de utilizador! Por favor, reveja e confirme as suas mudanças.", "group": "Grupo:", "group-user": "Utilizadores", @@ -1370,7 +1370,7 @@ "rcfilters-clear-all-filters": "Limpar todos os filtros", "rcfilters-search-placeholder": "Filtrar mudanças recentes (navegue ou começe a escrever)", "rcfilters-invalid-filter": "Filtro inválido", - "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.", + "rcfilters-empty-filter": "Não há filtros ativos. São mostradas todas as contribuições.", "rcfilters-filterlist-title": "Filtros", "rcfilters-filterlist-noresults": "Não foram encontrados filtros", "rcfilters-filtergroup-registration": "Registo de utilizador", @@ -1391,9 +1391,9 @@ "rcfilters-filter-userExpLevel-experienced-label": "Utilizadores experientes", "rcfilters-filter-userExpLevel-experienced-description": "Mais de 30 dias de atividade e 500 edições.", "rcfilters-filtergroup-automated": "Contribuições automatizadas", - "rcfilters-filter-bots-label": "Bot", + "rcfilters-filter-bots-label": "Robô", "rcfilters-filter-bots-description": "Edições efectuadas por ferramentas automatizadas.", - "rcfilters-filter-humans-label": "Humano (não bot)", + "rcfilters-filter-humans-label": "Ser humano (não robô)", "rcfilters-filter-humans-description": "Edições efectuadas por editores humanos.", "rcfilters-filtergroup-significance": "Significado", "rcfilters-filter-minor-label": "Edições menores", @@ -1402,7 +1402,7 @@ "rcfilters-filter-major-description": "Edições não marcadas como menores.", "rcfilters-filtergroup-changetype": "Tipo de alteração", "rcfilters-filter-pageedits-label": "Edições da página", - "rcfilters-filter-pageedits-description": "Edições do conteúdo wiki, discussões, descrições de categorias....", + "rcfilters-filter-pageedits-description": "Edições do conteúdo da wiki, de discussões, de descrições de categorias....", "rcfilters-filter-newpages-label": "Criações de páginas", "rcfilters-filter-newpages-description": "Edições que criam novas páginas.", "rcfilters-filter-categorization-label": "Alterações de categoria", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index b141ffc00d..d5c16a9577 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -1341,6 +1341,7 @@ "userrights-changeable-col": "Used when editing user groups in [[Special:Userrights]].\n\nThe message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language can do without.", "userrights-unchangeable-col": "Used when editing user groups in [[Special:Userrights]]. The message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language allows that.", "userrights-irreversible-marker": "{{optional}}\nParameters:\n* $1 - group member", + "userrights-no-shorten-expiry-marker": "{{optional}}\nParameters:\n* $1 - group member", "userrights-expiry-current": "Indicates when a user's membership of a user group expires.\n\nParameters:\n* $1 - time and date of expiry\n* $2 - date of expiry\n* $3 - time of expiry\n{{Identical|Expire}}", "userrights-expiry-none": "Indicates that a user's membership of a user group lasts indefinitely, and does not expire.", "userrights-expiry": "Used as a label for a form element which can be used to select an expiry date/time.\n{{Identical|Expire}}", @@ -1349,6 +1350,7 @@ "userrights-expiry-options": "{{doc-important|Be careful: '''1 translation:1 english''', so the first part is the translation and the second part should stay in English.}}\nOptions for the duration of the user group membership. Example: See e.g. [[MediaWiki:Userrights-expiry-options/nl]] if you still don't know how to do it.\n\nSee also {{msg-mw|protect-expiry-options}}.", "userrights-invalid-expiry": "Error message on [[Special:UserRights]].\n\nParameters:\n* $1 - group name", "userrights-expiry-in-past": "Error message on [[Special:UserRights]] when the user types an expiry date that has already passed.\n\nParameters:\n* $1 - group name", + "userrights-cannot-shorten-expiry": "Error message on [[Special:UserRights]] when the user tries to move the expiry date to be closer to the present and they do not have permission to do so. \"Bring forward\" is a phrasal verb meaning \"move to an earlier time\".\n\nParameters:\n* $1 - group name", "userrights-conflict": "Shown on [[Special:UserRights]] if the target's rights have been changed since the form was loaded.", "group": "{{Identical|Group}}", "group-user": "{{doc-group|user}}\n{{Identical|User}}", @@ -4324,6 +4326,7 @@ "mw-widgets-titleinput-description-new-page": "Description label for a new page in the title input widget.", "mw-widgets-titleinput-description-redirect": "Description label for a redirect in the title input widget.", "mw-widgets-categoryselector-add-category-placeholder": "Placeholder displayed in the category selector widget after the capsules of already added categories.", + "mw-widgets-usersmultiselect-placeholder": "Placeholder displayed in the input field, where new usernames are entered", "sessionmanager-tie": "Used as an error message when multiple session sources are tied in priority.\n\nParameters:\n* $1 - List of dession type descriptions, from messages like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.", "sessionprovider-generic": "Used to create a generic session type description when one isn't provided via the proper message. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.\n\nParameters:\n* $1 - PHP classname.", "sessionprovider-mediawiki-session-cookiesessionprovider": "Description of the sessions provided by the CookieSessionProvider class, which use HTTP cookies. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.", diff --git a/languages/i18n/tl.json b/languages/i18n/tl.json index d89ce497c5..30fe744e3b 100644 --- a/languages/i18n/tl.json +++ b/languages/i18n/tl.json @@ -405,7 +405,7 @@ "userloginnocreate": "Lumagda", "logout": "Umalis sa pagkaka-login", "userlogout": "Umalis sa pagkaka-login", - "notloggedin": "Hindi nakalagda", + "notloggedin": "Hindi naka-login", "userlogin-noaccount": "Wala ka pa bang account?", "userlogin-joinproject": "Sumali sa {{SITENAME}}", "nologin": "Wala ka pang account? $1.", diff --git a/languages/i18n/uk.json b/languages/i18n/uk.json index de199034de..d012feb33b 100644 --- a/languages/i18n/uk.json +++ b/languages/i18n/uk.json @@ -1104,6 +1104,7 @@ "username": "{{GENDER:$1|Ім'я користувача|Ім'я користувачки}}:", "prefs-memberingroups": "{{GENDER:$2|Член}} {{PLURAL:$1|1=групи|груп}}:", "prefs-memberingroups-type": "$1", + "group-membership-link-with-expiry": "$1 (до $2)", "prefs-registration": "Час реєстрації:", "prefs-registration-date-time": "$1", "yourrealname": "Справжнє ім'я:", @@ -1161,6 +1162,14 @@ "userrights-changeable-col": "Групи, які ви можете змінити", "userrights-unchangeable-col": "Групи, які ви не можете змінити", "userrights-irreversible-marker": "$1*", + "userrights-expiry-current": "Закінчується $1", + "userrights-expiry-none": "Не має терміну дії", + "userrights-expiry": "Минає:", + "userrights-expiry-existing": "Поточний час закінчення: $3, $2", + "userrights-expiry-othertime": "Інший термін/строк:", + "userrights-expiry-options": "1 день:1 day,1 тиждень:1 week,1 місяць:1 month,3 місяці:3 months,6 місяців:6 months,1 рік:1 year", + "userrights-invalid-expiry": "Для групи «$1» задано неправильний час закінчення прав.", + "userrights-expiry-in-past": "Для групи «$1» задано минулий час закінчення прав.", "userrights-conflict": "Конфлікт зміни прав користувача! Будь ласка, перевірте та підтвердіть зміни знову.", "group": "Група:", "group-user": "Користувачі", @@ -1362,22 +1371,49 @@ "recentchanges-legend-plusminus": "(''±123'')", "recentchanges-submit": "Показати", "rcfilters-activefilters": "Активні фільтри", + "rcfilters-restore-default-filters": "Відновити стандартні фільтри", + "rcfilters-clear-all-filters": "Очистити фільтри", "rcfilters-search-placeholder": "Фільтруйте нові редагування (переглядайте або почніть вводити)", "rcfilters-invalid-filter": "Недійсний фільтр", + "rcfilters-empty-filter": "Без фільтрів. Показано всі зміни.", "rcfilters-filterlist-title": "Фільтри", "rcfilters-filterlist-noresults": "Фільтри не знайдено", + "rcfilters-filtergroup-registration": "Реєстрація користувача", + "rcfilters-filter-registered-label": "Зареєстровані", + "rcfilters-filter-registered-description": "Користувачі, що увійшли в систему.", + "rcfilters-filter-unregistered-label": "Незареєстровані", + "rcfilters-filter-unregistered-description": "Користувачі, які не ввійшли в систему.", "rcfilters-filtergroup-authorship": "Авторство редагувань", "rcfilters-filter-editsbyself-label": "Ваші власні редагування", "rcfilters-filter-editsbyself-description": "Редагування, зроблені Вами.", "rcfilters-filter-editsbyother-label": "Редагування, зроблені іншими", - "rcfilters-filter-editsbyother-description": "Редагування, виконані іншими користувачами (не Вами)", - "rcfilters-filtergroup-userExpLevel": "Рівень досвіду користувачів", + "rcfilters-filter-editsbyother-description": "Редагування, виконані іншими користувачами (не Вами).", + "rcfilters-filtergroup-userExpLevel": "Рівень досвіду (тільки для зареєстрованих користувачів)", "rcfilters-filter-userExpLevel-newcomer-label": "Новачки", - "rcfilters-filter-userExpLevel-newcomer-description": "Дуже нові редактори: менш ніж 10 редагувань і 4 дні активності.", + "rcfilters-filter-userExpLevel-newcomer-description": "Менше ніж 10 редагувань і 4 дні активності.", "rcfilters-filter-userExpLevel-learner-label": "Учні", "rcfilters-filter-userExpLevel-learner-description": "Більше днів активності та більше редагувань, ніж у «новачків», але менше, ніж у «досвідчених користувачів».", "rcfilters-filter-userExpLevel-experienced-label": "Досвідчені користувачі", "rcfilters-filter-userExpLevel-experienced-description": "Більше 30 днів активності і понад 500 редагувань.", + "rcfilters-filtergroup-automated": "Автоматизовані редагування", + "rcfilters-filter-bots-label": "Бот", + "rcfilters-filter-bots-description": "Редагування, зроблені з допомогою автоматизованих засобів.", + "rcfilters-filter-humans-label": "Людина (не бот)", + "rcfilters-filter-humans-description": "Редагування, зроблені людиною.", + "rcfilters-filtergroup-significance": "Важливість", + "rcfilters-filter-minor-label": "Незначні редагування", + "rcfilters-filter-minor-description": "Редагування, позначені авторами як незначні.", + "rcfilters-filter-major-label": "Звичайні редагування", + "rcfilters-filter-major-description": "Редагування, не позначені як незначні.", + "rcfilters-filtergroup-changetype": "Вид зміни", + "rcfilters-filter-pageedits-label": "Редагування сторінок", + "rcfilters-filter-pageedits-description": "Редагування вікі-вмісту, обговорень, опису категорій тощо.", + "rcfilters-filter-newpages-label": "Створення сторінок", + "rcfilters-filter-newpages-description": "Редагування, якими створено нові сторінки.", + "rcfilters-filter-categorization-label": "Зміна категорій", + "rcfilters-filter-categorization-description": "Записи про додавання або вилучення сторінок з категорій.", + "rcfilters-filter-logactions-label": "Журнальні дії", + "rcfilters-filter-logactions-description": "Адміністративні дії, створення облікових записів, видалення сторінок, завантаження файлів тощо.", "rcnotefrom": "Нижче знаходяться {{PLURAL:$5|редагування}} з $3, $4 (відображено до $1).", "rclistfrom": "Показати редагування починаючи з $3 $2.", "rcshowhideminor": "$1 незначні редагування", @@ -1891,7 +1927,10 @@ "apisandbox-sending-request": "Надсилання запиту API…", "apisandbox-loading-results": "Отримання результатів API…", "apisandbox-results-error": "Сталася помилка при завантаженні відповіді на запит API: $1.", + "apisandbox-request-selectformat-label": "Показати запрошені дані як:", + "apisandbox-request-format-url-label": "URL-рядок", "apisandbox-request-url-label": "URL-адреса запиту:", + "apisandbox-request-json-label": "JSON запиту:", "apisandbox-request-time": "Час запиту: {{PLURAL:$1|$1 мс}}", "apisandbox-results-fixtoken": "Виправте токен і надішліть ще раз", "apisandbox-results-fixtoken-fail": "Не вдалося викликати токен «$1».", @@ -2036,7 +2075,7 @@ "emailccsubject": "Копія вашого повідомлення до $1: $2", "emailsent": "Електронне повідомлення надіслано", "emailsenttext": "Ваше електронне повідомлення надіслано.", - "emailuserfooter": "Цей лист був надісланий {{GENDER:$2|користувачеві|користувачці}} $2 від {{GENDER:$1|користувача|користувачки}} $1 за допомогою функції «{{int:emailuser}}» проекту {{SITENAME}}. {{GENDER:$2|Ваш}} електронний лист потрапить безпосередньо до {{GENDER:$1|початковго відправника|початкової відправниці}}, відкривши {{GENDER:$1|йому|їй}} {{GENDER:$2|Вашу}} електронну адресу.", + "emailuserfooter": "Цей лист був надісланий {{GENDER:$2|користувачеві|користувачці}} $2 від {{GENDER:$1|користувача|користувачки}} $1 за допомогою функції «{{int:emailuser}}» проекту {{SITENAME}}. Якщо Ви відповісте на цей лист, Ваш електронний лист буде надіслано безпосередньо до {{GENDER:$1|початковго відправника|початкової відправниці}}, відкривши {{GENDER:$1|йому|їй}} {{GENDER:$2|Вашу}} електронну адресу.", "usermessage-summary": "Залишити системне повідомлення.", "usermessage-editor": "Системний вісник", "usermessage-template": "MediaWiki:UserMessage", @@ -3697,6 +3736,7 @@ "logentry-tag-update-logentry": "$1 {{GENDER:$2|оновив|оновила}} мітки запису журналу $5 сторінки $3 ({{PLURAL:$7|додано}} $6; {{PLURAL:$9|вилучено}} $8)", "rightsnone": "(нема)", "revdelete-summary": "коментар до редагування", + "rightslogentry-temporary-group": "$1 (тимчасово, до $2)", "feedback-adding": "Додавання відгуку на сторінку ...", "feedback-back": "Назад", "feedback-bugcheck": "Чудово! Просто перевірте, що це не одна з вже [$1 відомих помилок].", diff --git a/languages/messages/MessagesJv.php b/languages/messages/MessagesJv.php index 3b788a3356..5488b9afa2 100644 --- a/languages/messages/MessagesJv.php +++ b/languages/messages/MessagesJv.php @@ -13,26 +13,34 @@ $fallback = 'id'; $namespaceNames = [ NS_MEDIA => 'Media', NS_SPECIAL => 'Astamiwa', - NS_TALK => 'Dhiskusi', + NS_TALK => 'Parembugan', NS_USER => 'Panganggo', - NS_USER_TALK => 'Dhiskusi_Panganggo', - NS_PROJECT_TALK => 'Dhiskusi_$1', + NS_USER_TALK => 'Parembugan_Panganggo', + NS_PROJECT_TALK => 'Parembugan_$1', NS_FILE => 'Gambar', - NS_FILE_TALK => 'Dhiskusi_Gambar', + NS_FILE_TALK => 'Parembugan_Gambar', NS_MEDIAWIKI => 'MediaWiki', - NS_MEDIAWIKI_TALK => 'Dhiskusi_MediaWiki', + NS_MEDIAWIKI_TALK => 'Parembugan_MediaWiki', NS_TEMPLATE => 'Cithakan', - NS_TEMPLATE_TALK => 'Dhiskusi_Cithakan', + NS_TEMPLATE_TALK => 'Parembugan_Cithakan', NS_HELP => 'Pitulung', - NS_HELP_TALK => 'Dhiskusi_Pitulung', + NS_HELP_TALK => 'Parembugan_Pitulung', NS_CATEGORY => 'Kategori', - NS_CATEGORY_TALK => 'Dhiskusi_Kategori', + NS_CATEGORY_TALK => 'Parembugan_Kategori', ]; -$namespaceAliases = [ - 'Gambar_Dhiskusi' => NS_FILE_TALK, +$namespaceAliases = [ // Kept former namespaces for backwards compatibility - T155957 + 'Cithakan_Dhiskusi' => NS_TEMPLATE_TALK, + 'Dhiskusi' => NS_TALK, + 'Dhiskusi_$1' => NS_PROJECT_TALK, + 'Dhiskusi_Cithakan' => NS_TEMPLATE_TALK, + 'Dhiskusi_Gambar' => NS_FILE_TALK, + 'Dhiskusi_Kategori' => NS_CATEGORY_TALK, + 'Dhiskusi_MediaWiki' => NS_MEDIAWIKI_TALK, + 'Dhiskusi_Panganggo' => NS_USER_TALK, + 'Dhiskusi_Pitulung' => NS_HELP_TALK, + 'Kategori_Dhiskusi' => NS_CATEGORY_TALK, 'MediaWiki_Dhiskusi' => NS_MEDIAWIKI_TALK, - 'Cithakan_Dhiskusi' => NS_TEMPLATE_TALK, - 'Pitulung_Dhiskusi' => NS_HELP_TALK, - 'Kategori_Dhiskusi' => NS_CATEGORY_TALK, + 'Pitulung_Dhiskusi' => NS_HELP_TALK, + 'Gambar_Dhiskusi' => NS_FILE_TALK, ]; diff --git a/maintenance/archives/patch-user_groups-primary-key.sql b/maintenance/archives/patch-user_groups-primary-key.sql new file mode 100644 index 0000000000..e3c8735660 --- /dev/null +++ b/maintenance/archives/patch-user_groups-primary-key.sql @@ -0,0 +1,5 @@ +-- Convert unique index into a primary key on user_groups + +ALTER TABLE /*$wgDBprefix*/user_groups + DROP INDEX ug_user_group, + ADD PRIMARY KEY (ug_user, ug_group); diff --git a/maintenance/archives/patch-user_groups-ug_expiry.sql b/maintenance/archives/patch-user_groups-ug_expiry.sql index 2ce2c9e84d..b329f9488d 100644 --- a/maintenance/archives/patch-user_groups-ug_expiry.sql +++ b/maintenance/archives/patch-user_groups-ug_expiry.sql @@ -1,7 +1,5 @@ --- Primary key and expiry column in user_groups table +-- Add expiry column in user_groups table ALTER TABLE /*$wgDBprefix*/user_groups - DROP INDEX ug_user_group, - ADD PRIMARY KEY (ug_user, ug_group), ADD COLUMN ug_expiry varbinary(14) NULL default NULL, ADD INDEX ug_expiry (ug_expiry); diff --git a/resources/Resources.php b/resources/Resources.php index f14787f815..70eef62f81 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -2367,6 +2367,15 @@ return [ ], 'targets' => [ 'desktop', 'mobile' ], ], + 'mediawiki.widgets.UsersMultiselectWidget' => [ + 'scripts' => [ + 'resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js', + ], + 'dependencies' => [ + 'oojs-ui-widgets', + ], + 'targets' => [ 'desktop', 'mobile' ], + ], 'mediawiki.widgets.SearchInputWidget' => [ 'scripts' => [ 'resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js', diff --git a/resources/lib/oojs-ui/i18n/fr.json b/resources/lib/oojs-ui/i18n/fr.json index 92015a4f59..a68c90f695 100644 --- a/resources/lib/oojs-ui/i18n/fr.json +++ b/resources/lib/oojs-ui/i18n/fr.json @@ -29,7 +29,8 @@ "SnowedEarth", "Jdforrester", "Wladek92", - "Harmonia Amanda" + "Harmonia Amanda", + "The RedBurn" ] }, "ooui-outline-control-move-down": "Descendre l’élément", @@ -41,7 +42,7 @@ "ooui-dialog-message-accept": "OK", "ooui-dialog-message-reject": "Annuler", "ooui-dialog-process-error": "Quelque chose s'est mal passé", - "ooui-dialog-process-dismiss": "Rejeter", + "ooui-dialog-process-dismiss": "Fermer", "ooui-dialog-process-retry": "Réessayer", "ooui-dialog-process-continue": "Continuer", "ooui-selectfile-button-select": "Sélectionner un fichier", diff --git a/resources/lib/oojs-ui/i18n/io.json b/resources/lib/oojs-ui/i18n/io.json new file mode 100644 index 0000000000..7d7b1b8337 --- /dev/null +++ b/resources/lib/oojs-ui/i18n/io.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Idojc" + ] + }, + "ooui-outline-control-move-down": "Movar elemento adsube", + "ooui-outline-control-move-up": "Movar elemento adsupere", + "ooui-outline-control-remove": "Forigar elemento", + "ooui-toolbar-more": "Plu multa", + "ooui-toolgroup-expand": "Plu multa", + "ooui-toolgroup-collapse": "Min multa", + "ooui-dialog-message-accept": "Aplikar", + "ooui-dialog-message-reject": "Anular", + "ooui-dialog-process-error": "Ulo faliis", + "ooui-dialog-process-dismiss": "Celar", + "ooui-dialog-process-retry": "Riprobar", + "ooui-dialog-process-continue": "Durar", + "ooui-selectfile-button-select": "Selektar dokumento", + "ooui-selectfile-not-supported": "Dokumento-selekto ne esas suportata", + "ooui-selectfile-placeholder": "Nula dokumento selektesis", + "ooui-selectfile-dragdrop-placeholder": "Pozar dokumento hike" +} diff --git a/resources/lib/oojs-ui/i18n/sr-ec.json b/resources/lib/oojs-ui/i18n/sr-ec.json index de52812e78..9d3b926dba 100644 --- a/resources/lib/oojs-ui/i18n/sr-ec.json +++ b/resources/lib/oojs-ui/i18n/sr-ec.json @@ -3,7 +3,8 @@ "authors": [ "Milicevic01", "Nikola Smolenski", - "Милан Јелисавчић" + "Милан Јелисавчић", + "Zoranzoki21" ] }, "ooui-outline-control-move-down": "Премести ставку на доле", @@ -19,5 +20,7 @@ "ooui-dialog-process-retry": "Покушај поново", "ooui-dialog-process-continue": "Настави", "ooui-selectfile-button-select": "Изабери датотеку", - "ooui-selectfile-placeholder": "Није изабрана ниједна датотека" + "ooui-selectfile-not-supported": "Избор датотеке није подржан", + "ooui-selectfile-placeholder": "Није изабрана ниједна датотека", + "ooui-selectfile-dragdrop-placeholder": "Додајте датотеку овде" } diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js b/resources/lib/oojs-ui/oojs-ui-apex.js index b93d59e133..124278b919 100644 --- a/resources/lib/oojs-ui/oojs-ui-apex.js +++ b/resources/lib/oojs-ui/oojs-ui-apex.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -41,5 +41,3 @@ OO.ui.ApexTheme.prototype.getDialogTransitionDuration = function () { OO.ui.theme = new OO.ui.ApexTheme(); }( OO ) ); - -//# sourceMappingURL=oojs-ui-apex.js.map \ No newline at end of file diff --git a/resources/lib/oojs-ui/oojs-ui-core-apex.css b/resources/lib/oojs-ui/oojs-ui-core-apex.css index 2bee712eaa..d2e9674e5a 100644 --- a/resources/lib/oojs-ui/oojs-ui-core-apex.css +++ b/resources/lib/oojs-ui/oojs-ui-core-apex.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-element-hidden { display: none !important; @@ -19,6 +19,9 @@ .oo-ui-buttonElement > .oo-ui-buttonElement-button { cursor: pointer; display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; vertical-align: middle; font-family: inherit; font-size: inherit; @@ -309,10 +312,6 @@ .oo-ui-fieldLayout .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup { z-index: 1; } -.oo-ui-fieldLayout .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content { - padding: 0.5em 0.75em; - line-height: 1.5; -} .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline .oo-ui-fieldLayout-help { margin-top: -0.3em; @@ -434,10 +433,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup { z-index: 1; } -.oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content { - padding: 0.5em 0.75em; - line-height: 1.4; -} .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-header { max-width: 50em; } @@ -489,7 +484,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { padding: 1.25em; } .oo-ui-panelLayout-framed { + border: 1px solid #ccc; border-radius: 0.5em; + box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25); } .oo-ui-panelLayout-padded.oo-ui-panelLayout-framed { margin: 1em 0; @@ -686,7 +683,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-popupWidget-body { clear: both; - overflow: hidden; +} +.oo-ui-popupWidget-body.oo-ui-clippableElement-clippable { + min-height: 1em; } .oo-ui-popupWidget-popup { background-color: #fff; @@ -736,8 +735,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupWidget-head > .oo-ui-labelElement-label { margin: 0.75em 1em; } +.oo-ui-popupWidget-body { + line-height: 1.4; +} .oo-ui-popupWidget-body-padded { - padding: 0 1em; + margin: 0.75em 1em; } .oo-ui-popupButtonWidget { position: relative; @@ -745,13 +747,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupButtonWidget .oo-ui-popupWidget { cursor: auto; } -.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget { +.oo-ui-popupWidget.oo-ui-popupButtonWidget-frameless-popup { /* @noflip */ - left: 0.9375em; + margin-left: 0.9375em; } -.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget { +.oo-ui-popupWidget.oo-ui-popupButtonWidget-framed-popup { /* @noflip */ - left: 1.2375em; + margin-left: 1.2375em; } .oo-ui-inputWidget { margin-right: 0.5em; @@ -861,14 +863,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { display: none; } .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget > .oo-ui-labelElement-label { +.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { display: block; position: absolute; top: 0; -} -.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { height: 100%; -webkit-touch-callout: none; -webkit-user-select: none; @@ -876,24 +874,21 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { -ms-user-select: none; user-select: none; } -.oo-ui-textInputWidget > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label { - left: 0; -} -.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label { - right: 0; -} .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-labelElement-label { +.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator { cursor: text; } .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator { cursor: pointer; } .oo-ui-textInputWidget.oo-ui-widget-disabled input, -.oo-ui-textInputWidget.oo-ui-widget-disabled textarea, +.oo-ui-textInputWidget.oo-ui-widget-disabled textarea { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label { -webkit-touch-callout: none; -webkit-user-select: none; @@ -901,6 +896,21 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { -ms-user-select: none; user-select: none; } +.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label { + display: block; +} +.oo-ui-textInputWidget > .oo-ui-iconElement-icon, +.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label { + left: 0; +} +.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator, +.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label { + right: 0; +} +.oo-ui-textInputWidget > .oo-ui-labelElement-label { + position: absolute; + top: 0; +} .oo-ui-textInputWidget-php > .oo-ui-iconElement-icon, .oo-ui-textInputWidget-php > .oo-ui-indicatorElement-indicator, .oo-ui-textInputWidget-php > .oo-ui-labelElement-label { @@ -998,6 +1008,12 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { overflow: hidden; opacity: 0; } +.oo-ui-menuSelectWidget.oo-ui-clippableElement-clippable { + min-height: 2.6em; +} +.oo-ui-menuSelectWidget-invisible { + display: none; +} .oo-ui-menuOptionWidget { position: relative; } @@ -1116,9 +1132,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-comboBoxInputWidget-dropdownButton > .oo-ui-buttonElement-button { display: block; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; overflow: hidden; } .oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty .oo-ui-comboBoxInputWidget-dropdownButton { @@ -1129,8 +1142,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { position: absolute; right: 0; top: 0; - height: 2.5em; width: 2.5em; + height: 2.5em; padding: 0; } .oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator { diff --git a/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css index 632c0854a3..004a244ad2 100644 --- a/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css +++ b/resources/lib/oojs-ui/oojs-ui-core-mediawiki.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-element-hidden { display: none !important; @@ -19,6 +19,9 @@ .oo-ui-buttonElement > .oo-ui-buttonElement-button { cursor: pointer; display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; vertical-align: middle; font-family: inherit; font-size: inherit; @@ -178,8 +181,8 @@ } .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button { padding: 0.546875em 1em; - min-height: 1.25em; - min-width: 1em; + min-height: 2.5em; + min-width: 3.125em; border-radius: 2px; position: relative; } @@ -447,10 +450,6 @@ .oo-ui-fieldLayout .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup { z-index: 1; } -.oo-ui-fieldLayout .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content { - padding: 0.5em 0.75em; - line-height: 1.5; -} .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help, .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline .oo-ui-fieldLayout-help { margin-top: -0.3em; @@ -575,10 +574,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup { z-index: 1; } -.oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content { - padding: 0.5em 0.75em; - line-height: 1.4; -} .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-header { max-width: 50em; } @@ -844,7 +839,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-popupWidget-body { clear: both; - overflow: hidden; +} +.oo-ui-popupWidget-body.oo-ui-clippableElement-clippable { + min-height: 1em; } .oo-ui-popupWidget-popup { background-color: #fff; @@ -894,8 +891,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupWidget-head > .oo-ui-labelElement-label { margin: 0.75em 1em; } +.oo-ui-popupWidget-body { + line-height: 1.4; +} .oo-ui-popupWidget-body-padded { - padding: 0 1em; + margin: 0.75em 1em; } .oo-ui-popupButtonWidget { position: relative; @@ -903,13 +903,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { .oo-ui-popupButtonWidget .oo-ui-popupWidget { cursor: auto; } -.oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget { +.oo-ui-popupWidget.oo-ui-popupButtonWidget-frameless-popup { /* @noflip */ - left: 0.9375em; + margin-left: 0.9375em; } -.oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget { +.oo-ui-popupWidget.oo-ui-popupButtonWidget-framed-popup { /* @noflip */ - left: 1.5em; + margin-left: 1.5em; } .oo-ui-inputWidget { margin-right: 0.5em; @@ -1226,14 +1226,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { display: none; } .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget > .oo-ui-labelElement-label { +.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { display: block; position: absolute; top: 0; -} -.oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator { height: 100%; -webkit-touch-callout: none; -webkit-user-select: none; @@ -1241,24 +1237,21 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { -ms-user-select: none; user-select: none; } -.oo-ui-textInputWidget > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label { - left: 0; -} -.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label { - right: 0; -} .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator, -.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-labelElement-label { +.oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator { cursor: text; } .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator { cursor: pointer; } .oo-ui-textInputWidget.oo-ui-widget-disabled input, -.oo-ui-textInputWidget.oo-ui-widget-disabled textarea, +.oo-ui-textInputWidget.oo-ui-widget-disabled textarea { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label { -webkit-touch-callout: none; -webkit-user-select: none; @@ -1266,6 +1259,21 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { -ms-user-select: none; user-select: none; } +.oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label { + display: block; +} +.oo-ui-textInputWidget > .oo-ui-iconElement-icon, +.oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label { + left: 0; +} +.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator, +.oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label { + right: 0; +} +.oo-ui-textInputWidget > .oo-ui-labelElement-label { + position: absolute; + top: 0; +} .oo-ui-textInputWidget-php > .oo-ui-iconElement-icon, .oo-ui-textInputWidget-php > .oo-ui-indicatorElement-indicator, .oo-ui-textInputWidget-php > .oo-ui-labelElement-label { @@ -1273,20 +1281,20 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-textInputWidget input, .oo-ui-textInputWidget textarea { + margin: 0; font-size: inherit; font-family: inherit; background-color: #fff; color: #000; border: 1px solid #a2a9b1; border-radius: 2px; + padding: 0.625em 0.546875em 0.546875em; } .oo-ui-textInputWidget input { - padding: 0.625em 0.546875em 0.546875em; line-height: 1.172em; } .oo-ui-textInputWidget textarea { - padding: 0.46875em 0.546875em 0.546875em; - line-height: 1.4; + line-height: 1.275; } .oo-ui-textInputWidget .oo-ui-pendingElement-pending { background-color: transparent; @@ -1351,50 +1359,51 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { border-color: #d33; box-shadow: inset 0 0 0 1px #d33; } +.oo-ui-textInputWidget.oo-ui-widget-disabled input, +.oo-ui-textInputWidget.oo-ui-widget-disabled textarea { + background-color: #eaecf0; + color: #72777d; + text-shadow: 0 1px 1px #fff; + border-color: #c8ccd1; +} +.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon, +.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator { + opacity: 0.51; +} +.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label { + color: #72777d; + text-shadow: 0 1px 1px #fff; +} .oo-ui-textInputWidget.oo-ui-iconElement input, .oo-ui-textInputWidget.oo-ui-iconElement textarea { - padding-left: 2.65625em; + padding-left: 2.875em; } .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon { - max-height: 2.5em; - left: 0.46875em; + left: 0; + height: 100%; + max-height: 2.375em; + margin-left: 0.5em; + background-position: right center; } .oo-ui-textInputWidget.oo-ui-indicatorElement input, .oo-ui-textInputWidget.oo-ui-indicatorElement textarea { padding-right: 2.4875em; } .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator { - max-height: 2.5em; - right: 0.625em; + height: 100%; + max-height: 2.375em; + margin: 0 0.775em; } .oo-ui-textInputWidget > .oo-ui-labelElement-label { color: #72777d; - right: 0.625em; - border: 1px solid transparent; - border-width: 1px 0; - padding: 0.625em 0 0.546875em; - line-height: 1.172em; + padding: 0.4em; + line-height: 1.5; } .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label { - right: 2.1875em; + margin-right: 2.0875em; } .oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label { - left: 2.65625em; -} -.oo-ui-textInputWidget.oo-ui-widget-disabled input, -.oo-ui-textInputWidget.oo-ui-widget-disabled textarea { - background-color: #eaecf0; - color: #72777d; - text-shadow: 0 1px 1px #fff; - border-color: #c8ccd1; -} -.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon, -.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator { - opacity: 0.51; -} -.oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label { - color: #72777d; - text-shadow: 0 1px 1px #fff; + margin-left: 2.475em; } .oo-ui-menuSelectWidget { position: absolute; @@ -1413,6 +1422,12 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { overflow: hidden; opacity: 0; } +.oo-ui-menuSelectWidget.oo-ui-clippableElement-clippable { + min-height: 2.6em; +} +.oo-ui-menuSelectWidget-invisible { + display: none; +} .oo-ui-menuOptionWidget { position: relative; padding: 0.5em 1em; @@ -1577,9 +1592,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { } .oo-ui-comboBoxInputWidget-dropdownButton > .oo-ui-buttonElement-button { display: block; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; overflow: hidden; } .oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty .oo-ui-comboBoxInputWidget-dropdownButton { @@ -1590,8 +1602,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { position: absolute; right: 0; top: 0; - height: 2.5em; width: 2.5em; + height: 2.5em; padding: 0; } .oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator { @@ -1608,8 +1620,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout { width: 2.5em; } .oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button { + min-width: 2.5em; min-height: 2.5em; - padding: 0.546875em; + padding-left: 0; + padding-right: 0; } .oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button, .oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button:focus { diff --git a/resources/lib/oojs-ui/oojs-ui-core.js b/resources/lib/oojs-ui/oojs-ui-core.js index 5dc78aba56..7cfa9c136b 100644 --- a/resources/lib/oojs-ui/oojs-ui-core.js +++ b/resources/lib/oojs-ui/oojs-ui-core.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -2922,17 +2922,6 @@ OO.ui.mixin.LabelElement.prototype.getLabel = function () { return this.label; }; -/** - * Fit the label. - * - * @chainable - * @deprecated since 0.16.0 - */ -OO.ui.mixin.LabelElement.prototype.fitLabel = function () { - OO.ui.warnDeprecation( 'LabelElement#fitLabel: This is a deprecated no-op.' ); - return this; -}; - /** * Set the content of the label. * @@ -3980,6 +3969,216 @@ OO.ui.mixin.PendingElement.prototype.popPending = function () { return this; }; +/** + * Element that will stick under a specified container, even when it is inserted elsewhere in the + * document (for example, in a OO.ui.Window's $overlay). + * + * The elements's position is automatically calculated and maintained when window is resized or the + * page is scrolled. If you reposition the container manually, you have to call #position to make + * sure the element is still placed correctly. + * + * As positioning is only possible when both the element and the container are attached to the DOM + * and visible, it's only done after you call #togglePositioning. You might want to do this inside + * the #toggle method to display a floating popup, for example. + * + * @abstract + * @class + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element + * @cfg {jQuery} [$floatableContainer] Node to position below + */ +OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) { + // Configuration initialization + config = config || {}; + + // Properties + this.$floatable = null; + this.$floatableContainer = null; + this.$floatableWindow = null; + this.$floatableClosestScrollable = null; + this.onFloatableScrollHandler = this.position.bind( this ); + this.onFloatableWindowResizeHandler = this.position.bind( this ); + + // Initialization + this.setFloatableContainer( config.$floatableContainer ); + this.setFloatableElement( config.$floatable || this.$element ); +}; + +/* Methods */ + +/** + * Set floatable element. + * + * If an element is already set, it will be cleaned up before setting up the new element. + * + * @param {jQuery} $floatable Element to make floatable + */ +OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) { + if ( this.$floatable ) { + this.$floatable.removeClass( 'oo-ui-floatableElement-floatable' ); + this.$floatable.css( { left: '', top: '' } ); + } + + this.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' ); + this.position(); +}; + +/** + * Set floatable container. + * + * The element will be always positioned under the specified container. + * + * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset + */ +OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) { + this.$floatableContainer = $floatableContainer; + if ( this.$floatable ) { + this.position(); + } +}; + +/** + * Toggle positioning. + * + * Do not turn positioning on until after the element is attached to the DOM and visible. + * + * @param {boolean} [positioning] Enable positioning, omit to toggle + * @chainable + */ +OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) { + var closestScrollableOfContainer; + + if ( !this.$floatable || !this.$floatableContainer ) { + return this; + } + + positioning = positioning === undefined ? !this.positioning : !!positioning; + + if ( this.positioning !== positioning ) { + this.positioning = positioning; + + closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] ); + this.needsCustomPosition = !OO.ui.contains( this.$floatableContainer[ 0 ], this.$floatable[ 0 ] ); + // If the scrollable is the root, we have to listen to scroll events + // on the window because of browser inconsistencies. + if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) { + closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer ); + } + + if ( positioning ) { + this.$floatableWindow = $( this.getElementWindow() ); + this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler ); + + this.$floatableClosestScrollable = $( closestScrollableOfContainer ); + this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler ); + + // Initial position after visible + this.position(); + } else { + if ( this.$floatableWindow ) { + this.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler ); + this.$floatableWindow = null; + } + + if ( this.$floatableClosestScrollable ) { + this.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler ); + this.$floatableClosestScrollable = null; + } + + this.$floatable.css( { left: '', top: '' } ); + } + } + + return this; +}; + +/** + * Check whether the bottom edge of the given element is within the viewport of the given container. + * + * @private + * @param {jQuery} $element + * @param {jQuery} $container + * @return {boolean} + */ +OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) { + var elemRect, contRect, + leftEdgeInBounds = false, + bottomEdgeInBounds = false, + rightEdgeInBounds = false; + + elemRect = $element[ 0 ].getBoundingClientRect(); + if ( $container[ 0 ] === window ) { + contRect = { + top: 0, + left: 0, + right: document.documentElement.clientWidth, + bottom: document.documentElement.clientHeight + }; + } else { + contRect = $container[ 0 ].getBoundingClientRect(); + } + + // For completeness, if we still cared about topEdgeInBounds, that'd be: + // elemRect.top >= contRect.top && elemRect.top <= contRect.bottom + if ( elemRect.left >= contRect.left && elemRect.left <= contRect.right ) { + leftEdgeInBounds = true; + } + if ( elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom ) { + bottomEdgeInBounds = true; + } + if ( elemRect.right >= contRect.left && elemRect.right <= contRect.right ) { + rightEdgeInBounds = true; + } + + // We only care that any part of the bottom edge is visible + return bottomEdgeInBounds && ( leftEdgeInBounds || rightEdgeInBounds ); +}; + +/** + * Position the floatable below its container. + * + * This should only be done when both of them are attached to the DOM and visible. + * + * @chainable + */ +OO.ui.mixin.FloatableElement.prototype.position = function () { + var pos; + + if ( !this.positioning ) { + return this; + } + + if ( !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) { + this.$floatable.addClass( 'oo-ui-element-hidden' ); + return; + } else { + this.$floatable.removeClass( 'oo-ui-element-hidden' ); + } + + if ( !this.needsCustomPosition ) { + return; + } + + pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() ); + + // Position under container + pos.top += this.$floatableContainer.height(); + this.$floatable.css( pos ); + + // We updated the position, so re-evaluate the clipping state. + // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so + // will not notice the need to update itself.) + // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does + // it not listen to the right events in the right places? + if ( this.clip ) { + this.clip(); + } + + return this; +}; + /** * Element that can be automatically clipped to visible boundaries. * @@ -4283,6 +4482,7 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () { * @extends OO.ui.Widget * @mixins OO.ui.mixin.LabelElement * @mixins OO.ui.mixin.ClippableElement + * @mixins OO.ui.mixin.FloatableElement * * @constructor * @param {Object} [config] Configuration options @@ -4328,6 +4528,7 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) { $clippable: this.$body, $clippableContainer: this.$popup } ) ); + OO.ui.mixin.FloatableElement.call( this, config ); // Properties this.$anchor = $( '
' ); @@ -4392,6 +4593,7 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) { OO.inheritClass( OO.ui.PopupWidget, OO.ui.Widget ); OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.LabelElement ); OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.ClippableElement ); +OO.mixinClass( OO.ui.PopupWidget, OO.ui.mixin.FloatableElement ); /* Methods */ @@ -4515,6 +4717,8 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) { OO.ui.PopupWidget.parent.prototype.toggle.call( this, show ); if ( change ) { + this.togglePositioning( show && !!this.$floatableContainer ); + if ( show ) { if ( this.autoClose ) { this.bindMouseDownListener(); @@ -4737,13 +4941,23 @@ OO.ui.mixin.PopupElement.prototype.getPopup = function () { * * @constructor * @param {Object} [config] Configuration options + * @cfg {jQuery} [$overlay] Render the popup into a separate layer. This configuration is useful in cases where + * the expanded popup is larger than its containing `
`. The specified overlay layer is usually on top of the + * containing `
` and has a larger area. By default, the popup uses relative positioning. */ OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) { // Parent constructor OO.ui.PopupButtonWidget.parent.call( this, config ); // Mixin constructors - OO.ui.mixin.PopupElement.call( this, config ); + OO.ui.mixin.PopupElement.call( this, $.extend( true, {}, config, { + popup: { + $floatableContainer: this.$element + } + } ) ); + + // Properties + this.$overlay = config.$overlay || this.$element; // Events this.connect( this, { click: 'onAction' } ); @@ -4751,8 +4965,12 @@ OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) { // Initialization this.$element .addClass( 'oo-ui-popupButtonWidget' ) - .attr( 'aria-haspopup', 'true' ) - .append( this.popup.$element ); + .attr( 'aria-haspopup', 'true' ); + this.popup.$element + .addClass( 'oo-ui-popupButtonWidget-popup' ) + .toggleClass( 'oo-ui-popupButtonWidget-framed-popup', this.isFramed() ) + .toggleClass( 'oo-ui-popupButtonWidget-frameless-popup', !this.isFramed() ); + this.$overlay.append( this.popup.$element ); }; /* Setup */ @@ -5054,6 +5272,19 @@ OO.ui.OptionWidget.prototype.setPressed = function ( state ) { return this; }; +/** + * Get text to match search strings against. + * + * The default implementation returns the label text, but subclasses + * can override this to provide more complex behavior. + * + * @return {string|boolean} String to match search string against + */ +OO.ui.OptionWidget.prototype.getMatchText = function () { + var label = this.getLabel(); + return typeof label === 'string' ? label : this.$label.text(); +}; + /** * A SelectWidget is of a generic selection of options. The OOjs UI library contains several types of * select widgets, including {@link OO.ui.ButtonSelectWidget button selects}, @@ -5498,7 +5729,7 @@ OO.ui.SelectWidget.prototype.onKeyPress = function ( e ) { * @protected * @param {string} s String to match against items * @param {boolean} [exact=false] Only accept exact matches - * @return {Function} function ( OO.ui.OptionItem ) => boolean + * @return {Function} function ( OO.ui.OptionWidget ) => boolean */ OO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) { var re; @@ -5513,14 +5744,11 @@ OO.ui.SelectWidget.prototype.getItemMatcher = function ( s, exact ) { } re = new RegExp( re, 'i' ); return function ( item ) { - var l = item.getLabel(); - if ( typeof l !== 'string' ) { - l = item.$label.text(); + var matchText = item.getMatchText(); + if ( matchText.normalize ) { + matchText = matchText.normalize(); } - if ( l.normalize ) { - l = l.normalize(); - } - return re.test( l ); + return re.test( matchText ); }; }; @@ -6192,7 +6420,8 @@ OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) { * @protected */ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () { - var i, item, + var i, item, visible, + anyVisible = false, len = this.items.length, showAll = !this.isVisible(), filter = showAll ? null : this.getItemMatcher( this.$input.val() ); @@ -6200,10 +6429,14 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () { for ( i = 0; i < len; i++ ) { item = this.items[ i ]; if ( item instanceof OO.ui.OptionWidget ) { - item.toggle( showAll || filter( item ) ); + visible = showAll || filter( item ); + anyVisible = anyVisible || visible; + item.toggle( visible ); } } + this.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible ); + // Reevaluate clipping this.clip(); }; @@ -7120,213 +7353,6 @@ OO.ui.CheckboxMultiselectWidget.prototype.onClick = function ( e ) { } }; -/** - * Element that will stick under a specified container, even when it is inserted elsewhere in the - * document (for example, in a OO.ui.Window's $overlay). - * - * The elements's position is automatically calculated and maintained when window is resized or the - * page is scrolled. If you reposition the container manually, you have to call #position to make - * sure the element is still placed correctly. - * - * As positioning is only possible when both the element and the container are attached to the DOM - * and visible, it's only done after you call #togglePositioning. You might want to do this inside - * the #toggle method to display a floating popup, for example. - * - * @abstract - * @class - * - * @constructor - * @param {Object} [config] Configuration options - * @cfg {jQuery} [$floatable] Node to position, assigned to #$floatable, omit to use #$element - * @cfg {jQuery} [$floatableContainer] Node to position below - */ -OO.ui.mixin.FloatableElement = function OoUiMixinFloatableElement( config ) { - // Configuration initialization - config = config || {}; - - // Properties - this.$floatable = null; - this.$floatableContainer = null; - this.$floatableWindow = null; - this.$floatableClosestScrollable = null; - this.onFloatableScrollHandler = this.position.bind( this ); - this.onFloatableWindowResizeHandler = this.position.bind( this ); - - // Initialization - this.setFloatableContainer( config.$floatableContainer ); - this.setFloatableElement( config.$floatable || this.$element ); -}; - -/* Methods */ - -/** - * Set floatable element. - * - * If an element is already set, it will be cleaned up before setting up the new element. - * - * @param {jQuery} $floatable Element to make floatable - */ -OO.ui.mixin.FloatableElement.prototype.setFloatableElement = function ( $floatable ) { - if ( this.$floatable ) { - this.$floatable.removeClass( 'oo-ui-floatableElement-floatable' ); - this.$floatable.css( { left: '', top: '' } ); - } - - this.$floatable = $floatable.addClass( 'oo-ui-floatableElement-floatable' ); - this.position(); -}; - -/** - * Set floatable container. - * - * The element will be always positioned under the specified container. - * - * @param {jQuery|null} $floatableContainer Container to keep visible, or null to unset - */ -OO.ui.mixin.FloatableElement.prototype.setFloatableContainer = function ( $floatableContainer ) { - this.$floatableContainer = $floatableContainer; - if ( this.$floatable ) { - this.position(); - } -}; - -/** - * Toggle positioning. - * - * Do not turn positioning on until after the element is attached to the DOM and visible. - * - * @param {boolean} [positioning] Enable positioning, omit to toggle - * @chainable - */ -OO.ui.mixin.FloatableElement.prototype.togglePositioning = function ( positioning ) { - var closestScrollableOfContainer, closestScrollableOfFloatable; - - positioning = positioning === undefined ? !this.positioning : !!positioning; - - if ( this.positioning !== positioning ) { - this.positioning = positioning; - - closestScrollableOfContainer = OO.ui.Element.static.getClosestScrollableContainer( this.$floatableContainer[ 0 ] ); - closestScrollableOfFloatable = OO.ui.Element.static.getClosestScrollableContainer( this.$floatable[ 0 ] ); - this.needsCustomPosition = closestScrollableOfContainer !== closestScrollableOfFloatable; - // If the scrollable is the root, we have to listen to scroll events - // on the window because of browser inconsistencies. - if ( $( closestScrollableOfContainer ).is( 'html, body' ) ) { - closestScrollableOfContainer = OO.ui.Element.static.getWindow( closestScrollableOfContainer ); - } - - if ( positioning ) { - this.$floatableWindow = $( this.getElementWindow() ); - this.$floatableWindow.on( 'resize', this.onFloatableWindowResizeHandler ); - - this.$floatableClosestScrollable = $( closestScrollableOfContainer ); - this.$floatableClosestScrollable.on( 'scroll', this.onFloatableScrollHandler ); - - // Initial position after visible - this.position(); - } else { - if ( this.$floatableWindow ) { - this.$floatableWindow.off( 'resize', this.onFloatableWindowResizeHandler ); - this.$floatableWindow = null; - } - - if ( this.$floatableClosestScrollable ) { - this.$floatableClosestScrollable.off( 'scroll', this.onFloatableScrollHandler ); - this.$floatableClosestScrollable = null; - } - - this.$floatable.css( { left: '', top: '' } ); - } - } - - return this; -}; - -/** - * Check whether the bottom edge of the given element is within the viewport of the given container. - * - * @private - * @param {jQuery} $element - * @param {jQuery} $container - * @return {boolean} - */ -OO.ui.mixin.FloatableElement.prototype.isElementInViewport = function ( $element, $container ) { - var elemRect, contRect, - leftEdgeInBounds = false, - bottomEdgeInBounds = false, - rightEdgeInBounds = false; - - elemRect = $element[ 0 ].getBoundingClientRect(); - if ( $container[ 0 ] === window ) { - contRect = { - top: 0, - left: 0, - right: document.documentElement.clientWidth, - bottom: document.documentElement.clientHeight - }; - } else { - contRect = $container[ 0 ].getBoundingClientRect(); - } - - // For completeness, if we still cared about topEdgeInBounds, that'd be: - // elemRect.top >= contRect.top && elemRect.top <= contRect.bottom - if ( elemRect.left >= contRect.left && elemRect.left <= contRect.right ) { - leftEdgeInBounds = true; - } - if ( elemRect.bottom >= contRect.top && elemRect.bottom <= contRect.bottom ) { - bottomEdgeInBounds = true; - } - if ( elemRect.right >= contRect.left && elemRect.right <= contRect.right ) { - rightEdgeInBounds = true; - } - - // We only care that any part of the bottom edge is visible - return bottomEdgeInBounds && ( leftEdgeInBounds || rightEdgeInBounds ); -}; - -/** - * Position the floatable below its container. - * - * This should only be done when both of them are attached to the DOM and visible. - * - * @chainable - */ -OO.ui.mixin.FloatableElement.prototype.position = function () { - var pos; - - if ( !this.positioning ) { - return this; - } - - if ( !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) { - this.$floatable.addClass( 'oo-ui-element-hidden' ); - return; - } else { - this.$floatable.removeClass( 'oo-ui-element-hidden' ); - } - - if ( !this.needsCustomPosition ) { - return; - } - - pos = OO.ui.Element.static.getRelativePosition( this.$floatableContainer, this.$floatable.offsetParent() ); - - // Position under container - pos.top += this.$floatableContainer.height(); - this.$floatable.css( pos ); - - // We updated the position, so re-evaluate the clipping state. - // (ClippableElement does not listen to 'scroll' events on $floatableContainer's parent, and so - // will not notice the need to update itself.) - // TODO: This is terrible, we shouldn't need to know about ClippableElement at all here. Why does - // it not listen to the right events in the right places? - if ( this.clip ) { - this.clip(); - } - - return this; -}; - /** * FloatingMenuSelectWidget is a menu that will stick under a specified * container, even when it is inserted elsewhere in the document (for example, @@ -9930,7 +9956,7 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) { * @throws {Error} An error is thrown if no widget is specified */ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) { - var hasInputWidget, $div; + var hasInputWidget; // Allow passing positional parameters inside the config object if ( OO.isPlainObject( fieldWidget ) && config === undefined ) { @@ -9966,20 +9992,18 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) { this.align = null; if ( config.help ) { this.popupButtonWidget = new OO.ui.PopupButtonWidget( { + popup: { + padded: true + }, classes: [ 'oo-ui-fieldLayout-help' ], framed: false, icon: 'info' } ); - - $div = $( '
' ); if ( config.help instanceof OO.ui.HtmlSnippet ) { - $div.html( config.help.toString() ); + this.popupButtonWidget.getPopup().$body.html( config.help.toString() ); } else { - $div.text( config.help ); + this.popupButtonWidget.getPopup().$body.text( config.help ); } - this.popupButtonWidget.getPopup().$body.append( - $div.addClass( 'oo-ui-fieldLayout-help-content' ) - ); this.$help = this.popupButtonWidget.$element; } else { this.$help = $( [] ); @@ -10283,8 +10307,6 @@ OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout ); * For important messages, you are advised to use `notices`, as they are always shown. */ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) { - var $div; - // Configuration initialization config = config || {}; @@ -10300,20 +10322,18 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) { this.$header = $( '
' ); if ( config.help ) { this.popupButtonWidget = new OO.ui.PopupButtonWidget( { + popup: { + padded: true + }, classes: [ 'oo-ui-fieldsetLayout-help' ], framed: false, icon: 'info' } ); - - $div = $( '
' ); if ( config.help instanceof OO.ui.HtmlSnippet ) { - $div.html( config.help.toString() ); + this.popupButtonWidget.getPopup().$body.html( config.help.toString() ); } else { - $div.text( config.help ); + this.popupButtonWidget.getPopup().$body.text( config.help ); } - this.popupButtonWidget.getPopup().$body.append( - $div.addClass( 'oo-ui-fieldsetLayout-help-content' ) - ); this.$help = this.popupButtonWidget.$element; } else { this.$help = $( [] ); @@ -10586,5 +10606,3 @@ OO.inheritClass( OO.ui.HorizontalLayout, OO.ui.Layout ); OO.mixinClass( OO.ui.HorizontalLayout, OO.ui.mixin.GroupElement ); }( OO ) ); - -//# sourceMappingURL=oojs-ui-core.js.map \ No newline at end of file diff --git a/resources/lib/oojs-ui/oojs-ui-mediawiki.js b/resources/lib/oojs-ui/oojs-ui-mediawiki.js index 32daabdb2b..05b578aaf8 100644 --- a/resources/lib/oojs-ui/oojs-ui-mediawiki.js +++ b/resources/lib/oojs-ui/oojs-ui-mediawiki.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -82,5 +82,3 @@ OO.ui.MediaWikiTheme.prototype.getDialogTransitionDuration = function () { OO.ui.theme = new OO.ui.MediaWikiTheme(); }( OO ) ); - -//# sourceMappingURL=oojs-ui-mediawiki.js.map \ No newline at end of file diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css b/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css index d781e68806..327c4d5514 100644 --- a/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css +++ b/resources/lib/oojs-ui/oojs-ui-toolbars-apex.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-popupTool .oo-ui-popupWidget-popup, .oo-ui-popupTool .oo-ui-popupWidget-anchor { @@ -276,12 +276,17 @@ -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )"; } .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { - top: 2.5em; margin: 0 -1px; border: 1px solid #ccc; background-color: #fff; box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25); } +.oo-ui-toolbar-position-top .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { + top: 2.5em; +} +.oo-ui-toolbar-position-bottom .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { + bottom: 2.5em; +} .oo-ui-popupToolGroup .oo-ui-tool-link { padding: 0.3125em 0 0.3125em 0.3125em; } @@ -455,7 +460,6 @@ pointer-events: none; } .oo-ui-toolbar-bar { - border-bottom: 1px solid #ccc; background-color: #f8fbfd; background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #F1F7FB)); background-image: -webkit-linear-gradient(top, #fff 0, #F1F7FB 100%); @@ -463,6 +467,12 @@ background-image: linear-gradient(to bottom, #fff 0, #F1F7FB 100%); -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#fff1f7fb' )"; } +.oo-ui-toolbar-position-top .oo-ui-toolbar-bar { + border-bottom: 1px solid #ccc; +} +.oo-ui-toolbar-position-bottom .oo-ui-toolbar-bar { + border-top: 1px solid #ccc; +} .oo-ui-toolbar-bar .oo-ui-toolbar-bar { border: 0; background: none; diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css index 986024031b..86af796bc5 100644 --- a/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css +++ b/resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-tool.oo-ui-widget-enabled { -webkit-transition: background-color 100ms; @@ -239,13 +239,18 @@ left: 0; } .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { - top: 3.125em; margin: 0 -1px; border: 1px solid #c8ccd1; background-color: #fff; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.25); min-width: 16em; } +.oo-ui-toolbar-position-top .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { + top: 3.125em; +} +.oo-ui-toolbar-position-bottom .oo-ui-popupToolGroup .oo-ui-toolGroup-tools { + bottom: 3.125em; +} .oo-ui-popupToolGroup .oo-ui-tool-link { padding: 0.4em 0.625em; -webkit-box-sizing: border-box; @@ -404,12 +409,17 @@ .oo-ui-toolbar-bar { background-color: #fff; color: #222; - border-bottom: 1px solid #c8ccd1; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); font-weight: 500; } +.oo-ui-toolbar-position-top .oo-ui-toolbar-bar { + border-bottom: 1px solid #c8ccd1; +} +.oo-ui-toolbar-position-bottom .oo-ui-toolbar-bar { + border-top: 1px solid #c8ccd1; +} .oo-ui-toolbar-bar .oo-ui-toolbar-bar { - border-bottom: 0; + border: 0; background-color: transparent; box-shadow: none; } diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars.js b/resources/lib/oojs-ui/oojs-ui-toolbars.js index 0b8a7f6530..1ab99e2dd7 100644 --- a/resources/lib/oojs-ui/oojs-ui-toolbars.js +++ b/resources/lib/oojs-ui/oojs-ui-toolbars.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -293,6 +293,7 @@ * in the toolbar, but are not configured as tools. By default, actions are displayed on the right side of * the toolbar. * @cfg {boolean} [shadow] Add a shadow below the toolbar. + * @cfg {string} [position='top'] Whether the toolbar is positioned above ('top') or below ('bottom') content. */ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) { // Allow passing positional parameters inside the config object @@ -317,6 +318,7 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) { this.toolGroupFactory = toolGroupFactory; this.groups = []; this.tools = {}; + this.position = config.position || 'top'; this.$bar = $( '
' ); this.$actions = $( '
' ); this.initialized = false; @@ -339,7 +341,7 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) { if ( config.shadow ) { this.$bar.append( '
' ); } - this.$element.addClass( 'oo-ui-toolbar' ).append( this.$bar ); + this.$element.addClass( 'oo-ui-toolbar oo-ui-toolbar-position-' + this.position ).append( this.$bar ); }; /* Setup */ @@ -1775,7 +1777,9 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) { } // Configuration initialization - config = config || {}; + config = $.extend( { + indicator: toolbar.position === 'bottom' ? 'up' : 'down' + }, config ); // Parent constructor OO.ui.PopupToolGroup.parent.call( this, toolbar, config ); @@ -2010,7 +2014,6 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) { * // Configurations for list toolgroup. * type: 'list', * label: 'ListToolGroup', - * indicator: 'down', * icon: 'ellipsis', * title: 'This is the title, displayed when user moves the mouse over the list toolgroup', * header: 'This is the header', @@ -2240,7 +2243,6 @@ OO.ui.ListToolGroup.prototype.updateCollapsibleState = function () { * type: 'menu', * header: 'This is the (optional) header', * title: 'This is the (optional) title', - * indicator: 'down', * include: [ 'settings', 'stuff' ] * } * ] ); @@ -2329,5 +2331,3 @@ OO.ui.MenuToolGroup.prototype.onUpdateState = function () { }; }( OO ) ); - -//# sourceMappingURL=oojs-ui-toolbars.js.map \ No newline at end of file diff --git a/resources/lib/oojs-ui/oojs-ui-widgets-apex.css b/resources/lib/oojs-ui/oojs-ui-widgets-apex.css index ec581c1473..610df2c939 100644 --- a/resources/lib/oojs-ui/oojs-ui-widgets-apex.css +++ b/resources/lib/oojs-ui/oojs-ui-widgets-apex.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-draggableElement-handle, .oo-ui-draggableElement-handle.oo-ui-widget { @@ -729,6 +729,14 @@ .oo-ui-capsuleMultiselectWidget-group { display: inline; } +.oo-ui-capsuleMultiselectWidget-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > * { + display: block; +} +.oo-ui-capsuleMultiselectWidget-focusTrap { + display: inline-block; + height: 1px; + width: 1px; +} .oo-ui-capsuleMultiselectWidget-handle { background-color: #fff; cursor: text; @@ -793,6 +801,9 @@ .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator { opacity: 0.2; } +.oo-ui-capsuleMultiselectWidget-popup > .oo-ui-popupWidget-popup { + border: 0; +} .oo-ui-capsuleItemWidget { position: relative; display: inline-block; @@ -880,11 +891,6 @@ .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget { display: table-cell; } -.oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} .oo-ui-numberInputWidget-field { display: table; table-layout: fixed; diff --git a/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css index aced25b6e7..68a5acc079 100644 --- a/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css +++ b/resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-draggableElement-handle, .oo-ui-draggableElement-handle.oo-ui-widget { @@ -805,6 +805,14 @@ .oo-ui-capsuleMultiselectWidget-group { display: inline; } +.oo-ui-capsuleMultiselectWidget-popup > .oo-ui-popupWidget-popup > .oo-ui-popupWidget-body > * { + display: block; +} +.oo-ui-capsuleMultiselectWidget-focusTrap { + display: inline-block; + height: 1px; + width: 1px; +} .oo-ui-capsuleMultiselectWidget-handle { min-height: 2.4em; margin-right: 0.5em; @@ -869,17 +877,11 @@ top: 0; margin: 0.3em; } -.oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget { - width: 100%; +.oo-ui-capsuleMultiselectWidget-popup { margin-top: -1px; } -.oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget-popup { - min-width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - border-width: 0 1px; - border-radius: 0 0 2px 2px; +.oo-ui-capsuleMultiselectWidget-popup > .oo-ui-popupWidget-popup { + border: 0; } .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled .oo-ui-capsuleMultiselectWidget-handle { background-color: #fff; @@ -1009,11 +1011,6 @@ .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget { display: table-cell; } -.oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} .oo-ui-numberInputWidget-field { display: table; table-layout: fixed; @@ -1024,6 +1021,7 @@ } .oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button { display: block; + min-width: 2.5em; min-height: 2.5em; padding-left: 0; padding-right: 0; diff --git a/resources/lib/oojs-ui/oojs-ui-widgets.js b/resources/lib/oojs-ui/oojs-ui-widgets.js index 4bf461f996..55f1c9c8da 100644 --- a/resources/lib/oojs-ui/oojs-ui-widgets.js +++ b/resources/lib/oojs-ui/oojs-ui-widgets.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -1779,11 +1779,9 @@ OO.ui.BookletLayout.prototype.onStackLayoutVisibleItemChange = function ( page ) OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) { var layout = this; if ( !this.scrolling && page ) { - page.scrollElementIntoView( { - complete: function () { - if ( layout.autoFocus && !OO.ui.isMobile() ) { - layout.focus(); - } + page.scrollElementIntoView().done( function () { + if ( layout.autoFocus && !OO.ui.isMobile() ) { + layout.focus(); } } ); } @@ -2290,11 +2288,9 @@ OO.ui.IndexLayout.prototype.onStackLayoutFocus = function ( e ) { OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) { var layout = this; if ( card ) { - card.scrollElementIntoView( { - complete: function () { - if ( layout.autoFocus && !OO.ui.isMobile() ) { - layout.focus(); - } + card.scrollElementIntoView().done( function () { + if ( layout.autoFocus && !OO.ui.isMobile() ) { + layout.focus(); } } ); } @@ -3615,7 +3611,11 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) align: 'forwards', anchor: false } ); - OO.ui.mixin.PopupElement.call( this, config ); + OO.ui.mixin.PopupElement.call( this, $.extend( true, {}, config, { + popup: { + $floatableContainer: this.$element + } + } ) ); $tabFocus = $( '' ); OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: $tabFocus } ) ); } else { @@ -3695,12 +3695,16 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) this.$element.addClass( 'oo-ui-capsuleMultiselectWidget' ) .append( this.$handle ); if ( this.popup ) { + this.popup.$element.addClass( 'oo-ui-capsuleMultiselectWidget-popup' ); this.$content.append( $tabFocus ); this.$overlay.append( this.popup.$element ); } else { this.$content.append( this.$input ); this.$overlay.append( this.menu.$element ); } + if ( $tabFocus ) { + $tabFocus.addClass( 'oo-ui-capsuleMultiselectWidget-focusTrap' ); + } // Input size needs to be calculated after everything else is rendered setTimeout( function () { @@ -4305,7 +4309,7 @@ OO.ui.CapsuleMultiselectWidget.prototype.setDisabled = function ( disabled ) { OO.ui.CapsuleMultiselectWidget.prototype.focus = function () { if ( !this.isDisabled() ) { if ( this.popup ) { - this.popup.setSize( this.$handle.width() ); + this.popup.setSize( this.$handle.outerWidth() ); this.popup.toggle( true ); OO.ui.findFocusable( this.popup.$element ).focus(); } else { @@ -5345,5 +5349,3 @@ OO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) { }; }( OO ) ); - -//# sourceMappingURL=oojs-ui-widgets.js.map \ No newline at end of file diff --git a/resources/lib/oojs-ui/oojs-ui-windows-apex.css b/resources/lib/oojs-ui/oojs-ui-windows-apex.css index 2fc4cc8d19..61691b8543 100644 --- a/resources/lib/oojs-ui/oojs-ui-windows-apex.css +++ b/resources/lib/oojs-ui/oojs-ui-windows-apex.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-actionWidget.oo-ui-pendingElement-pending { background-image: /* @embed */ url(themes/apex/images/textures/pending.gif); diff --git a/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css b/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css index c643c28684..6f3298a899 100644 --- a/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css +++ b/resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:32Z + * Date: 2017-02-01T23:04:44Z */ .oo-ui-window { background: transparent; diff --git a/resources/lib/oojs-ui/oojs-ui-windows.js b/resources/lib/oojs-ui/oojs-ui-windows.js index ab83a55228..11e63cb16e 100644 --- a/resources/lib/oojs-ui/oojs-ui-windows.js +++ b/resources/lib/oojs-ui/oojs-ui-windows.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.18.4-fix (d4045dee45) + * OOjs UI v0.19.0 * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2017 OOjs UI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: 2017-01-19T20:22:26Z + * Date: 2017-02-01T23:04:40Z */ ( function ( OO ) { @@ -1455,11 +1455,8 @@ OO.ui.WindowManager.prototype.addWindows = function ( windows ) { list = {}; for ( i = 0, len = windows.length; i < len; i++ ) { name = windows[ i ].constructor.static.name; - if ( typeof name !== 'string' ) { - throw new Error( 'Cannot add window' ); - } if ( !name ) { - OO.ui.warnDeprecation( 'OO.ui.WindowManager#addWindows: Windows must have a `name` static property defined.' ); + throw new Error( 'Windows must have a `name` static property defined.' ); } list[ name ] = windows[ i ]; } @@ -3496,5 +3493,3 @@ OO.ui.prompt = function ( text, options ) { }; }( OO ) ); - -//# sourceMappingURL=oojs-ui-windows.js.map \ No newline at end of file diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less index f138d7e55b..b58dfdf6c9 100644 --- a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less +++ b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less @@ -24,6 +24,11 @@ &-search { max-width: none; margin-top: -0.5em; + + input { + // Make sure this uses the interface direction, not the content direction + direction: ltr; + } } &-capsule-invalid-filter { diff --git a/resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js b/resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js index 7f5e608f91..0ec6a4c518 100644 --- a/resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js +++ b/resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js @@ -72,6 +72,8 @@ * while the widget is inactive. Should be as unambiguous as possible (for example, prefer to * spell out the month, rather than rely on the order), even if that makes it longer. When not * given, the default is language-specific. + * @cfg {boolean} [longDisplayFormat=false] If a custom displayFormat is not specified, use + * unabbreviated day of the week and month names in the default language-specific displayFormat. * @cfg {string} [placeholderLabel=No date selected] Placeholder text shown when the widget is not * selected. Default text taken from message `mw-widgets-dateinput-no-date`. * @cfg {string} [placeholderDateFormat] User-visible date format string displayed in the textual input @@ -92,6 +94,7 @@ // Config initialization config = $.extend( { precision: 'day', + longDisplayFormat: false, required: false, placeholderLabel: mw.msg( 'mw-widgets-dateinput-no-date' ) }, config ); @@ -129,6 +132,7 @@ this.inTextInput = 0; this.inputFormat = config.inputFormat; this.displayFormat = config.displayFormat; + this.longDisplayFormat = config.longDisplayFormat; this.required = config.required; this.placeholderLabel = config.placeholderLabel; @@ -439,6 +443,10 @@ ll = localeData.longDateFormat( 'll' ); format = llll.replace( lll.replace( ll, '' ), '' ); + if ( this.longDisplayFormat ) { + format = format.replace( 'MMM', 'MMMM' ).replace( 'ddd', 'dddd' ); + } + return format; } }; diff --git a/resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js b/resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js new file mode 100644 index 0000000000..70d7cb50f2 --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js @@ -0,0 +1,163 @@ +/*! + * MediaWiki Widgets - UsersMultiselectWidget class. + * + * @copyright 2017 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ +( function ( $, mw ) { + + /** + * UsersMultiselectWidget can be used to input list of users in a single + * line. + * + * If used inside HTML form the results will be sent as the list of + * newline-separated usernames. + * + * @class + * @extends OO.ui.CapsuleMultiselectWidget + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries + * @cfg {number} [limit=10] Number of results to show in autocomplete menu + * @cfg {string} [name] Name of input to submit results (when used in HTML forms) + */ + mw.widgets.UsersMultiselectWidget = function MwWidgetsUsersMultiselectWidget( config ) { + // Config initialization + config = $.extend( { + limit: 10 + }, config, { + // Because of using autocomplete (constantly changing menu), we need to + // allow adding usernames, which do not present in the menu. + allowArbitrary: true + } ); + + // Parent constructor + mw.widgets.UsersMultiselectWidget.parent.call( this, $.extend( {}, config, {} ) ); + + // Mixin constructors + OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) ); + + // Properties + this.limit = config.limit; + + if ( 'name' in config ) { + // If used inside HTML form, then create hidden input, which will store + // the results. + this.hiddenInput = $( '' ) + .attr( 'type', 'hidden' ) + .attr( 'name', config.name ) + .appendTo( this.$element ); + + // Update with preset values + this.updateHiddenInput(); + } + + this.menu = this.getMenu(); + + // Events + // Update contents of autocomplete menu as user types letters + this.$input.on( { + keyup: this.updateMenuItems.bind( this ) + } ); + // When option is selected from autocomplete menu, update the menu + this.menu.connect( this, { + select: 'updateMenuItems' + } ); + // When list of selected usernames changes, update hidden input + this.connect( this, { + change: 'updateHiddenInput' + } ); + + // API init + this.api = config.api || new mw.Api(); + }; + + /* Setup */ + + OO.inheritClass( mw.widgets.UsersMultiselectWidget, OO.ui.CapsuleMultiselectWidget ); + OO.mixinClass( mw.widgets.UsersMultiselectWidget, OO.ui.mixin.PendingElement ); + + /* Methods */ + + /** + * Get currently selected usernames + * + * @return {Array} usernames + */ + mw.widgets.UsersMultiselectWidget.prototype.getSelectedUsernames = function() { + return this.getItemsData(); + }; + + /** + * Update autocomplete menu with items + * + * @private + */ + mw.widgets.UsersMultiselectWidget.prototype.updateMenuItems = function() { + var inputValue = this.$input.val(); + + if ( inputValue === this.inputValue ) { + // Do not restart api query if nothing has changed in the input + return; + } else { + this.inputValue = inputValue; + } + + this.api.abort(); // Abort all unfinished api requests + + if ( inputValue.length > 0 ) { + this.pushPending(); + + this.api.get( { + action: 'query', + list: 'allusers', + // Prefix of list=allusers is case sensitive. Normalise first + // character to uppercase so that "fo" may yield "Foo". + auprefix: inputValue[ 0 ].toUpperCase() + inputValue.slice( 1 ), + aulimit: this.limit + } ).done( function( response ) { + var suggestions = response.query.allusers, + selected = this.getSelectedUsernames(); + + // Remove usernames, which are already selected from suggestions + suggestions = suggestions.map( function ( user ) { + if ( selected.indexOf( user.name ) === -1 ) { + return new OO.ui.MenuOptionWidget( { + data: user.name, + label: user.name + } ); + } + } ).filter( function( item ) { + return item !== undefined; + } ); + + // Remove all items from menu add fill it with new + this.menu.clearItems(); + + // Additional check to prevent bug of autoinserting first suggestion + // while removing user from the list + if ( inputValue.length > 1 || suggestions.length > 1 ) { + this.menu.addItems( suggestions ); + } + + this.popPending(); + }.bind( this ) ).fail( this.popPending.bind( this ) ); + } else { + this.menu.clearItems(); + } + }; + + /** + * If used inside HTML form, then update hiddenInput with list o + * newline-separated usernames. + * + * @private + */ + mw.widgets.UsersMultiselectWidget.prototype.updateHiddenInput = function() { + if ( 'hiddenInput' in this ) { + this.hiddenInput.val( this.getSelectedUsernames().join( '\n' ) ); + } + }; + +}( jQuery, mediaWiki ) ); diff --git a/resources/src/mediawiki/api.js b/resources/src/mediawiki/api.js index d5032da8f4..5abd2d4fa9 100644 --- a/resources/src/mediawiki/api.js +++ b/resources/src/mediawiki/api.js @@ -486,7 +486,7 @@ 'stashwrongowner', 'stashnosuchfilekey' ]; - mw.log.deprecate( mw.Api, 'errors', mw.Api.errors ); + mw.log.deprecate( mw.Api, 'errors', mw.Api.errors, 'mw.Api.errors' ); /** * @static @@ -498,6 +498,6 @@ 'duplicate', 'exists' ]; - mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings ); + mw.log.deprecate( mw.Api, 'warnings', mw.Api.warnings, 'mw.Api.warnings' ); }( mediaWiki, jQuery ) ); diff --git a/tests/phpunit/includes/TestLogger.php b/tests/phpunit/includes/TestLogger.php index 7086a926be..84a6adf2ac 100644 --- a/tests/phpunit/includes/TestLogger.php +++ b/tests/phpunit/includes/TestLogger.php @@ -38,9 +38,11 @@ class TestLogger extends \Psr\Log\AbstractLogger { private $filter = null; /** - * @param bool $collect Whether to collect logs + * @param bool $collect Whether to collect logs. @see setCollect() * @param callable $filter Filter logs before collecting/printing. Signature is * string|null function ( string $message, string $level, array $context ); + * @param bool $collectContext Whether to keep the context passed to log. + * @since 1.29 @see setCollectContext() */ public function __construct( $collect = false, $filter = null, $collectContext = false ) { $this->collect = $collect; @@ -51,9 +53,23 @@ class TestLogger extends \Psr\Log\AbstractLogger { /** * Set the "collect" flag * @param bool $collect + * @return TestLogger $this */ public function setCollect( $collect ) { $this->collect = $collect; + return $this; + } + + /** + * Set the collectContext flag + * + * @param bool $collectContext + * @since 1.29 + * @return TestLogger $this + */ + public function setCollectContext( $collectContext ) { + $this->collectContext = $collectContext; + return $this; } /** diff --git a/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php b/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php index 97ea23cd8a..e3ea13915d 100644 --- a/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php +++ b/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php @@ -17,7 +17,9 @@ class RCFeedIntegrationTest extends MediaWikiTestCase { /** * @covers RecentChange::notifyRCFeeds * @covers RecentChange::getEngine - * @covers RCFeedEngine + * @covers RCFeed::factory + * @covers FormattedRCFeed::__construct + * @covers FormattedRCFeed::notify * @covers JSONRCFeedFormatter::formatArray * @covers MachineReadableRCFeedFormatter::getLine */